简体   繁体   English

Flutter,如何获取小部件的大小?

[英]Flutter, How to get the size of a widget?

I came across this example to get the Size/Position of a widget: https://medium.com/@diegoveloper/flutter-widget-size-and-position-b0a9ffed9407我遇到了这个例子来获取小部件的大小/位置: https : //medium.com/@diegoveloper/flutter-widget-size-and-position-b0a9ffed9407

what is wrong with my code?我的代码有什么问题?

I get the error:我收到错误:

The following NoSuchMethodError was thrown while handling a gesture:
I/flutter ( 8566): The method 'findRenderObject' was called on null.
I/flutter ( 8566): Receiver: null
I/flutter ( 8566): Tried calling: findRenderObject()
void main() {
      runApp(new MyApp());
    }

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(home: MyWidgetSizeTMP());
      }
    }

    class MyWidgetSizeTMP extends StatefulWidget{
      @override
      MyWidgetSizeTMPState createState() {
        return new MyWidgetSizeTMPState();
      }
    }

    class MyWidgetSizeTMPState extends State<MyWidgetSizeTMP> {

      //creating Key for red panel
      GlobalKey _keyRed = GlobalKey();

      _getSizes() {
        final RenderBox renderBoxRed = _keyRed.currentContext.findRenderObject();
        final sizeRed = renderBoxRed.size;
        print("SIZE of Red: $sizeRed");
      }

      _getPositions() {
        final RenderBox renderBoxRed = _keyRed.currentContext.findRenderObject();
        final positionRed = renderBoxRed.localToGlobal(Offset.zero);
        print("POSITION of Red: $positionRed ");
      }

      _afterLayout(_) {
        _getSizes();
        _getPositions();
      }

      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        WidgetsBinding.instance.addPostFrameCallback(_afterLayout);
      }

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
          ),
          body: Column(
            children: <Widget>[
              Flexible(
                flex: 2,
                child: Container(
                  color: Colors.red,
                ),
              ),
              Flexible(
                flex: 1,
                child: Container(
                  color: Colors.purple,
                ),
              ),
              Flexible(
                flex: 3,
                child: Container(
                  color: Colors.green,
                ),
              ),
              Spacer(),
              Padding(
                padding: const EdgeInsets.only(bottom: 8.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    MaterialButton(
                      elevation: 5.0,
                      padding: EdgeInsets.all(15.0),
                      color: Colors.grey,
                      child: Text("Get Sizes"),
                      onPressed: _getSizes,
                    ),
                    MaterialButton(
                      elevation: 5.0,
                      color: Colors.grey,
                      padding: EdgeInsets.all(15.0),
                      child: Text("Get Positions"),
                      onPressed: _getPositions,
                    )
                  ],
                ),
              )
            ],
          ),
        );
      }
    }

You can wrap in LayoutBuilder:您可以在 LayoutBuilder 中包装:

return LayoutBuilder(
    builder: (BuildContext context, BoxConstraints constraints) {
//      height: constraints.maxHeight,
//      width: constraints.maxWidth
        return YourWidget();
    }
);

This is because the _keyRed is not attached to Context in your code.这是因为_keyRed未附加到代码中的 Context。

to fix it -要解决这个问题 -

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _keyRed,  //Add this.
      appBar: AppBar(

In the link you referred to, after creating the GlobalKey it is assigned to the red container在您提到的链接中,创建GlobalKey后,它被分配给红色容器

but in your code you haven't assigned it to the container so it can be referred to from the _getSizes() and _getPositions() , _keyRed have to be attached to a Context in your code before you use it.但是在您的代码中,您尚未将其分配给容器,因此可以从_getSizes()_getPositions()引用它,在使用之前必须将_keyRed附加到代码中的上下文。

//creating Key for red panel
GlobalKey _keyRed = GlobalKey();
    ...
    //set key
        Flexible(
                 flex: 2,
                 child: Container(
                   key: _keyRed, // assigned as a key of the red container.
                   color: Colors.red,
                 ),
         ),

There is no direct way to calculate the size of the widget, so to find that we have to take the help of the context of the widget.没有直接的方法来计算widget的大小,所以要找到我们必须借助widget的上下文。

Calling context.size returns us the Size object, which contains the height and width of the widget.调用 context.size 会返回 Size 对象,其中包含小部件的高度和宽度。 context.size calculates the render box of a widget and returns the size. context.size 计算小部件的渲染框并返回大小。

Checkout https://medium.com/flutterworld/flutter-how-to-get-the-height-of-the-widget-be4892abb1a2结帐https://medium.com/flutterworld/flutter-how-to-get-the-height-of-the-widget-be4892abb1a2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM