【问题标题】:How to avoid child rebuilding if parent updates如果父更新,如何避免子重建
【发布时间】:2021-06-29 02:20:08
【问题描述】:

我有一个奇怪的要求。我看到了这个this question on SO,但我无法让它适用于我的情况。

我有一个代表我的屏幕的动画容器。按添加图标。我正在转换屏幕like this(右侧图像中的列位于主屏幕下方)。但是在那个 AnimatedContainer 里面有一个 LIST(作为孩子)。

每次我做转换。该列表正在重新构建自己。有什么办法可以避免。 ?

您可以想象主屏幕被固定在墙上,左右顶部有两个钉子。当我按 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();
  }
}

当您按下 + 图标时,您会看到。屏幕变换和列表正在重建。

【问题讨论】:

    标签: flutter dart flutter-layout flutter-animation


    【解决方案1】:

    请使用这个类, https://api.flutter.dev/flutter/widgets/AnimatedBuilder-class.html

    性能优化

    如果您的构建器函数包含不依赖于 动画,构建一次子树效率更高 在每个动画滴答声中重建它。

    如果您将预先构建的子树作为子参数传递,则 AnimatedBuilder 会将其传递回您的构建器函数,以便您 可以将其合并到您的构建中。

    【讨论】:

    • 我添加了最少的代码来重现该问题。你能再看看它。 ?
    【解决方案2】:

    您可以使用提供程序库轻松实现此目的。 试试看吧?

    【讨论】:

    • 我对提供者不太好。我添加了最少的代码来重现该问题。你能再看看它。并解释我如何进一步进行
    【解决方案3】:

    如果你是初学者,我会推荐使用 Getx

    有应用开发经验的话我会

    建议使用 Bloc 库检查这两个

    酒馆

    【讨论】:

    • 我添加了最少的代码来重现该问题。你能不能再看看它。给我一些方向
    猜你喜欢
    • 2020-06-11
    • 1970-01-01
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    • 2011-12-04
    • 2023-04-03
    • 1970-01-01
    相关资源
    最近更新 更多