【问题标题】:get height of a Widget using its GlobalKey in flutter在颤动中使用其 GlobalKey 获取 Widget 的高度
【发布时间】:2018-10-11 10:17:09
【问题描述】:

我正在努力使用其 GlobalKey 获取 Widget 的高度。 在渲染布局后调用获取高度的函数以确保上下文可用,但 key.currentState 和 key.currentContext 仍然返回 null。

import 'package:flutter/material.dart';

class TestPage extends StatefulWidget{
  @override
  State<StatefulWidget> createState() => new TestPageState();
}

class TestPageState extends State<TestPage>{
  final TestWidget testWidget = new TestWidget();

  @override
  initState() {
    //calling the getHeight Function after the Layout is Rendered
    WidgetsBinding.instance
        .addPostFrameCallback((_) => getHeight());

    super.initState();
  }

  void getHeight(){
    final GlobalKey key = testWidget.key;

    //returns null:
    final State state = key.currentState;
    //returns null:
    final BuildContext context = key.currentContext;

    //Error: The getter 'context' was called on null.
    final RenderBox box = state.context.findRenderObject();

    print(box.size.height);
    print(context.size.height);
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: testWidget,
    );
  }
}

class TestWidget extends StatefulWidget{
  @override
  Key get key => new GlobalKey<TestWidgetState>();

  @override
  State<StatefulWidget> createState() => new TestWidgetState();
}

class TestWidgetState extends State<TestWidget>{
  @override
  Widget build(BuildContext context) {
    return new Container(
      child: new Text("Test", style: const TextStyle(fontSize: 32.0, fontWeight: FontWeight.bold),),
    );
  }
}

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    您需要在小部件构造函数中使用super 将该键分配给小部件。不要将其添加为字段。 Key 也必须是常量。

    import 'package:flutter/material.dart';
    
    class TestPage extends StatefulWidget {
      @override
      State<StatefulWidget> createState() => new TestPageState();
    }
    
    class TestPageState extends State<TestPage> {
      final key = new GlobalKey<TestWidgetState>();
    
      @override
      initState() {
        //calling the getHeight Function after the Layout is Rendered
        WidgetsBinding.instance.addPostFrameCallback((_) => getHeight());
    
        super.initState();
      }
    
      void getHeight() {
        //returns null:
        final State state = key.currentState;
        //returns null:
        final BuildContext context = key.currentContext;
    
        //Error: The getter 'context' was called on null.
        final RenderBox box = state.context.findRenderObject();
    
        print(box.size.height);
        print(context.size.height);
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          body: new TestWidget(key: key),
        );
      }
    }
    
    class TestWidget extends StatefulWidget {
      TestWidget({Key key}) : super(key: key);
    
      @override
      State<StatefulWidget> createState() => new TestWidgetState();
    }
    
    class TestWidgetState extends State<TestWidget> {
      @override
      Widget build(BuildContext context) {
        return new Container(
          child: new Text(
            "Test",
            style: const TextStyle(fontSize: 32.0, fontWeight: FontWeight.bold),
          ),
        );
      }
    }
    

    【讨论】:

    • 上面的代码给出了这个错误 //Error: The getter 'context' was called on null.
    • @AsadJamil 如果您尝试通过runApp(TestPage()); 运行它,它将返回此错误,但如果您将 TestPage 包装在 MediaQuery 和 Directionality 小部件(提供数据和 textDirection 参数)或 MaterialApp 或WidgetsApp 小部件,它应该可以运行(或者至少对我有用)。
    • @AsadJamil 但是,在您的示例中,密钥不是恒定的。
    【解决方案2】:

    像这样定义你的构造函数:

    const MyWidget(GlobalKey key) : super(key:key);.

    框架将BuildContextState 对象存储在Widget.key 字段中,该字段由构造函数而不是任意key 字段传递给对象。

    【讨论】:

      【解决方案3】:

      有时更好的方法是使用 LayoutBuilder。在这种情况下,代码看起来像

      return LayoutBuilder(
        builder: (context, constraints) {
          print('Available container sizes - ${constraints.maxWidth} - ${constraints.maxHeight}');
          return Container(
            child: new Text(
              "Test",
              style: const TextStyle(fontSize: 32.0, fontWeight: FontWeight.bold),
            ),
          );
        },
      );
      

      这种方法动态地提供信息,通常对动画很有用。

      【讨论】:

        猜你喜欢
        • 2020-02-12
        • 2018-08-24
        • 2020-06-03
        • 2020-11-02
        • 1970-01-01
        • 2019-05-25
        • 1970-01-01
        • 2020-09-02
        • 2021-03-07
        相关资源
        最近更新 更多