在颤动中使用其 GlobalKey 获取 Widget 的高度
Posted
技术标签:
【中文标题】在颤动中使用其 GlobalKey 获取 Widget 的高度【英文标题】:get height of a Widget using its GlobalKey in flutter 【发布时间】: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),),
);
【问题讨论】:
【参考方案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);
.
框架将BuildContext
和State
对象存储在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),
),
);
,
);
这种方法动态地提供信息,通常对动画很有用。
【讨论】:
以上是关于在颤动中使用其 GlobalKey 获取 Widget 的高度的主要内容,如果未能解决你的问题,请参考以下文章
flutter通过GlobalKey在自定义Widget外部获取其state刷新页面