簡體   English   中英

如果父更新,如何避免子重建

[英]How to avoid child rebuilding if parent updates

我有一個奇怪的要求。 在 SO 上看到了這個問題,但我無法讓它適用於我的情況。

我有一個代表我的屏幕的動畫容器。 按添加圖標。 我正在像這樣轉換屏幕(右側圖像中的列位於主屏幕下方)。 但是在那個 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();
  }
}

您可以看到當您按下+圖標時。 屏幕轉換和列表正在重建。

請使用這個 class, https://api.flutter.dev/flutter/widgets/AnimatedBuilder-class.ZFC35FZ888A829

性能優化

如果您的構建器 function 包含不依賴於 animation 的子樹,則構建該子樹一次而不是在每個 animation 滴答時重新構建它會更有效。

如果您將預構建的子樹作為子參數傳遞,AnimatedBuilder 會將其傳遞回您的構建器 function,以便您可以將其合並到您的構建中。

您可以使用提供程序庫輕松實現此目的。 試試看

如果你是 r 初學者,我會推薦使用 Getx

有應用程序開發經驗,然后我會

建議使用 Bloc 庫檢查它們

酒吧。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM