我有一个奇怪的要求。我看到这个this question on SO但我无法让它适用于我的情况。
我有一个代表我的屏幕的动画容器。按添加图标。我在改造屏幕like this (右侧图像中的列在主屏幕下方)。但是在那个 AnimatedContainer 里面有一个 LIST(作为 child )。
每次我做转换。该列表正在重新构建。有什么办法可以避免它。 ?
您可以想象主屏幕是用左右顶部的两个钉子钉在墙上的。当我按下 FAB 时。拔出左上钉,屏幕卡在右钉托上。当我再次按下 FAB 时,左上角再次被钉住。
这是我正在使用的小部件
https://pub.dev/packages/matrix4_transform
这里是查看重建的最少代码
import 'package:flutter/material.dart';
import 'package:matrix4_transform/matrix4_transform.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: MyStatefulWidget(),
);
}
}
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key? key}) : super(key: key);
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
_MyStatefulWidgetState? home;
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
DrawerManager drawerManager = DrawerManager();
callSetState() {
setState(() {});
}
@override
Widget build(BuildContext context) {
print('Rebuild');
home = this;
return AnimatedContainer(
transform: Matrix4Transform()
.translate(x: drawerManager.xOffSet, y: drawerManager.yOffSet)
.rotate(drawerManager.angle)
.matrix4,
duration: Duration(milliseconds: 500),
child: Scaffold(
body: MyList(drawerManager),
),
);
}
}
class MyList extends StatelessWidget {
final Data myData = Data();
final DrawerManager drawerManager;
MyList(this.drawerManager);
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: myData.data.length+1,
itemBuilder: (context, index) {
print('Building list' + index.toString());
if(index == 4){
return GestureDetector(
child: IconButton(
icon: Icon(Icons.add),
onPressed: () {
drawerManager.callback(drawerManager.isOpened);
}),
);
}
else{return ListTile(
title: Text(myData.data[index]),
);}
},
),
);
}
}
class Data {
List<String> data = ['Hello1', 'Hello2', 'Hello3', 'Hello4'];
}
class DrawerManager {
double xOffSet = 0;
double yOffSet = 0;
double angle = 0;
bool isOpened = false;
void callback(bool isOpen) {
print('Tapped');
if (isOpen) {
xOffSet = 0;
yOffSet = 0;
angle = 0;
isOpened = false;
} else {
xOffSet = 150;
yOffSet = 80;
angle = -0.2;
isOpened = true;
}
callSetState();
}
void callSetState() {
home!.callSetState();
}
}
当您按下 + 图标时,您会看到。屏幕转换和列表正在重建。
最佳答案
请使用这个类, https://api.flutter.dev/flutter/widgets/AnimatedBuilder-class.html
Performance optimizations
If your builder function contains a subtree that does not depend on the animation, it's more efficient to build that subtree once instead of rebuilding it on every animation tick.
If you pass the pre-built subtree as the child parameter, the AnimatedBuilder will pass it back to your builder function so that you can incorporate it into your build.
关于flutter - 如果 parent 更新,如何避免重建 child ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66915451/