Flutter 如何获取父窗口中动画值的子窗口小部件大小
虽然颤振正在增长,但有很多建议和“方法”。我不确定什么是正确的,因为我对这个框架真的很陌生 比如,我有以下代码(几乎没有减少):Flutter 如何获取父窗口中动画值的子窗口小部件大小,flutter,dart,Flutter,Dart,虽然颤振正在增长,但有很多建议和“方法”。我不确定什么是正确的,因为我对这个框架真的很陌生 比如,我有以下代码(几乎没有减少): @覆盖 小部件构建(构建上下文){ 返回手势检测器( //此处需要动画值的高度 子:堆栈( 儿童:[ 定位( 左:0,, 右:0,, 底部:值, 子:列(//总高度 儿童:[ 容器(高度:60),//1 容器(高度:150),//2 集装箱(高度:200), ], ), ), ], )); } 在GestureDetector中,我正在为一些小部件动作设置动画,这取
@覆盖
小部件构建(构建上下文){
返回手势检测器(
//此处需要动画值的高度
子:堆栈(
儿童:[
定位(
左:0,,
右:0,,
底部:值,
子:列(//总高度
儿童:[
容器(高度:60),//1
容器(高度:150),//2
集装箱(高度:200),
],
),
),
],
));
}
在GestureDetector
中,我正在为一些小部件动作设置动画,这取决于其子部件的不同高度
儿童//1
和//2
(以及第三个)的高度将在开发时设置为硬编码,但是,由于有几个这样的元素和自定义小部件,我想自动获取它们。稍后,这是更好的维护,因为几乎每个小部件都有一些动画
因此,我可以使用GlobalKey
,或者可能使用BoxConstraints
,但是——总之——如果构建为自定义小部件,最便宜的方法是什么
结束这个问题:在GestureDetector
中,我能够在完成初始布局和每次重建后重建
我只是不确定哪种方法是安全的,并且成本最低(代码中有好几次这些小部件)
<> > <代码> // 1 < /代码>和<代码> // 2代码>:<代码> // 1代码>代码>初始动画>代码>开始:Valuy,<代码> //5>代码>是中间停止的值,<代码> //整体高度是动画<代码>结束:< /代码>值。只是解释一下
至少:我在所有这些中都使用了states\u rebuilder
。我们只需在呈现小部件后获得其大小,除非它是常量。
我们可以使用ValueNotifier在渲染后发送子对象的大小
下面是它的完整示例
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ValueNotifier<Size> _size = ValueNotifier<Size>(Size(0, 0));
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("example")
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ValueListenableBuilder(
builder: (BuildContext context, Size value, Widget child) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text('Height of the child: ${value.height}'),
Text('Width of the child: ${value.width}'),
SizeTrackingWidget(
child: Container(
height: MediaQuery.of(context).size.width*0.4,
width: MediaQuery.of(context).size.width*0.3,
color: Colors.red
),
sizeValueNotifier: _size,
)
],
);
},
valueListenable: _size,
child: null,
)
],
),
),
);
}
}
class SizeTrackingWidget extends StatefulWidget {
Widget child;
ValueNotifier<Size> sizeValueNotifier;
SizeTrackingWidget({Key key, @required this.sizeValueNotifier, @required this.child}) : super(key: key);
@override
_SizeTrackingWidgetState createState() => _SizeTrackingWidgetState();
}
class _SizeTrackingWidgetState extends State<SizeTrackingWidget> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_){
_getSize();
});
}
_getSize() {
RenderBox renderBox = context.findRenderObject();
widget.sizeValueNotifier.value = renderBox.size;
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}
导入“包装:颤振/材料.省道”;
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
//此小部件是应用程序的根。
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
),
主页:MyHomePage(),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key}):超级(Key:Key);
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState扩展状态{
ValueNotifier_size=ValueNotifier(大小(0,0));
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(“示例”)
),
正文:中(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
ValueListenableBuilder(
生成器:(BuildContext上下文、大小值、小部件子项){
返回列(
mainAxisAlignment:mainAxisAlignment.space,
儿童:[
Text('子级的高度:${value.Height}'),
Text('子项的宽度:${value.Width}'),
SizeTrackingWidget(
子:容器(
高度:MediaQuery.of(上下文).size.width*0.4,
宽度:MediaQuery.of(context).size.width*0.3,
颜色:颜色。红色
),
sizeValueNotifier:\u大小,
)
],
);
},
valueListenable:\u大小,
child:null,
)
],
),
),
);
}
}
类SizeTrackingWidget扩展StatefulWidget{
小部件儿童;
ValueNotifier sizeValueNotifier;
SizeTrackingWidget({Key-Key,@required this.sizeValueNotifier,@required this.child}):超级(Key:Key);
@凌驾
_SizeTrackingWidgetState createState()=>\u SizeTrackingWidgetState();
}
类_SizeTrackingWidgetState扩展状态{
@凌驾
void initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((){
_getSize();
});
}
_getSize(){
RenderBox RenderBox=context.findenderobject();
widget.sizeValueNotifier.value=renderBox.size;
}
@凌驾
小部件构建(构建上下文){
返回widget.child;
}
}
受@Thang Mai的公认答案启发,我提出了一个类似的无状态解决方案:
class ChildSizeNotifier extends StatelessWidget {
final ValueNotifier<Size> notifier = ValueNotifier(const Size(0, 0));
final Widget Function(BuildContext context, Size size, Widget child) builder;
final Widget child;
UjChildSizeNotifier({
Key key,
@required this.builder,
this.child,
}) : super(key: key) {}
@override
Widget build(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback(
(_) {
notifier.value = (context.findRenderObject() as RenderBox).size;
},
);
return ValueListenableBuilder(
valueListenable: notifier,
builder: builder,
child: child,
);
}
}
这听起来很有趣!非常感谢,为了更好地理解,我将执行此操作。只有当值(将在某一时间)发生更改时,此操作才会起作用?在这种情况下,我的值heigt
是硬编码的,可能永远不会更改,但我希望通过代码获得height
,以便于维护,而不是为所有这些值都设置几个常量。这两种情况下都适用。如果将高度设置为200,则渲染后,它还将返回等于200的高度。您应该注意,当小部件进入屏幕并呈现时,它将返回小部件的实际大小。好的,我将在接下来的几天实现它。谢谢你这也解决了一些其他的问题,所以我想把这个标记为可接受的答案。谢谢,干得真不错!
ChildSizeNotifier(
builder: (context, size, child) {
// size is the size of the text
return Text(size.height > 50 ? 'big' : 'small');
},
)