如何获取小部件的位置,以便在加载时定位另一个小部件

时间:2020-08-12 09:04:17

标签: flutter dart

我发现了几种方法来解释如何在按下按钮等时获取小部件的位置,但是每当我尝试获取小部件的位置时(在initState,didChangeDependencies期间或在主小部件构建方法之后),为了相对于第一个放置另一个小部件,我得到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()),
        ],
      ),
    );
  }
}

1 个答案:

答案 0 :(得分:1)

您可以在下面复制粘贴运行完整代码
您可以在addPostFrameCallback中使用initState
代码段

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();
    });

工作演示

enter image description here

完整代码

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(),
    );
  }
}