Reputation: 2034
I've found several methods explaining how to get the location of a widget when pressing a button etc but whenever I try to get the location of a widget (during initState, didChangeDependencies, or after the main widget build method), in order to position another widget relative to the first ,I get findRenderObject was called on null
...
import 'package:flutter/material.dart';
class Example extends StatefulWidget {
@override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
GlobalKey _key = GlobalKey();
RenderBox renderBox;
void _getWidgetPosition(){
renderBox = _key.currentContext.findRenderObject();
final position = renderBox.localToGlobal(Offset.zero);
print(position);
}
@override
void initState(){
super.initState();
// Getting the position doesn't work here
}
@override
void didChangeDependencies(){
super.didChangeDependencies();
// Getting the position doesn't work here
}
@override
Widget build(BuildContext context) {
// Getting the position doesn't work here
return Scaffold(
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
FloatingActionButton(onPressed: () => _getWidgetPosition()),
FloatingActionButton(
onPressed: null,
key: _key,
),
FloatingActionButton(onPressed: null)
],
),
body: Stack(
children: <Widget>[
Positioned(
// This is where I would like to use the middle FAB's position
// left: ,
// top: ,
child: Container()),
],
),
);
}
}
Upvotes: 1
Views: 2739
Reputation: 54367
You can copy paste run full code below
You can use addPostFrameCallback
in initState
code snippet
class _ExampleState extends State<Example> {
GlobalKey _key = GlobalKey();
RenderBox renderBox;
Offset position = Offset.zero;
void _getWidgetPosition() {
renderBox = _key.currentContext.findRenderObject();
position = renderBox.localToGlobal(Offset.zero);
print(position);
setState(() {});
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_getWidgetPosition();
});
working demo
full code
import 'package:flutter/material.dart';
class Example extends StatefulWidget {
@override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
GlobalKey _key = GlobalKey();
RenderBox renderBox;
Offset position = Offset.zero;
void _getWidgetPosition() {
renderBox = _key.currentContext.findRenderObject();
position = renderBox.localToGlobal(Offset.zero);
print(position);
setState(() {});
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_getWidgetPosition();
});
// Getting the position doesn't work here
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
// Getting the position doesn't work here
}
@override
Widget build(BuildContext context) {
print(position.dx);
// Getting the position doesn't work here
return Scaffold(
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
FloatingActionButton(onPressed: () => _getWidgetPosition()),
FloatingActionButton(
onPressed: null,
key: _key,
),
FloatingActionButton(onPressed: null)
],
),
body: Stack(
children: <Widget>[
Positioned(
left: position.dx,
top: position.dy,
child: Container(
color: Colors.orange,
width: 100,
height: 100,
)),
],
),
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Example(),
);
}
}
Upvotes: 2