简体   繁体   English

Flutter Widget 重建的行为

[英]Behavior of Flutter Widget rebuild

I have a simple Flutter program that creates a List of Buttons.我有一个简单的 Flutter 程序,可以创建一个按钮列表。 When I click one Button, the button disappears and the others are shifted up one position.当我单击一个按钮时,该按钮消失,其他按钮上移一个位置。 I made several versions, and in one of them the first time that the App is created, I prepare a List of ElevatedButton Widgets, so that the next time that build() is called, I return those already created, a sort of cache.我制作了几个版本,其中一个在第一次创建应用程序时,我准备了一个 ElevatedButton 小部件列表,以便下次调用 build() 时,我返回那些已经创建的缓存。 When I run the App in Android Studio and track Widget rebuilds on the Flutter performance window, It appears that they are rebuilt, even if the old ones are used (see debug prints).当我在 Android Studio 中运行应用程序并在 Flutter 性能窗口上跟踪 Widget 重建时,即使使用旧的,它们似乎也已重建(参见调试打印)。 Obviously the Widgets every time are identical, Can somebody explain if the widgets are really recreated?显然小部件每次都是相同的,有人可以解释小部件是否真的重新创建? Would there be any benefits in my implementation?我的实施会有什么好处吗?

import 'dart:async';
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:should_rebuild/should_rebuild.dart';

void main() {
  Get.put(Controller());
  runApp(MaterialApp(home: HomePage()));
}

class Controller extends GetxController {
  RxList<String> tutti = RxList();
  List<ElevatedButton> righe = [];
  List<int> posizioni = [];

  void add(ElevatedButton r) {
    righe.add(r);
    posizioni.add(posizioni.length);
  }

  Widget at(int index) => righe[index];

  @override
  onInit() {
    for (int i = 0; i < 10; i++) {
      tutti.add('item $i');
    }
  }

  void aggiorna(int index) {
    for (int i = 0; i < posizioni.length; i++) {
      // keep widget positios updated, if any widget before them in the list is removed
      if (posizioni[i] == index) {
        righe.removeAt(i);
        tutti.removeAt(i);
        posizioni.removeAt(i);
        break;
      }
    }
  }
}

class MyList extends StatelessWidget {
  const MyList({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final Controller controller = Get.find();
    return Obx(() => ListView.builder(
        itemCount: controller.tutti.value.length,
        itemBuilder: (context, index) {
          if (index >= controller.righe.length) {
            // missing, create a new one
            print ('create button');
            ElevatedButton r = ElevatedButton(
                  child: Text(controller.tutti.value[index]),
                  onPressed: () {
                    controller.aggiorna(index);
                  },
                );

            controller.add(r);
            return r;
          } else {
            //     return existing
            print ('reuse button');
            return controller.at(index);
          }
        }));
  }
}

class HomePage extends StatelessWidget {
  HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('hello'),
        ),
        body: Center(child: const MyList()));
  }
}

You put your Controller in the main function so when ever the app rebuilds in development the main function is run again which overrides all the previous data in variables.您将控制器放在主函数中,因此当应用程序在开发中重建时,主函数会再次运行,它会覆盖变量中的所有先前数据。

The cache will work maybe when its running in release mode but then too if the app gets cleared from the memory it loses all the state/data so the list you had buttons in is empty.缓存在发布模式下运行时可能会起作用,但如果应用程序从内存中清除,它也会丢失所有状态/数据,因此您拥有按钮的列表为空。

Speaking to the best of my knowledge and as per I understand the working.据我所知,并根据我的理解工作。 If you find something that says otherwise very eager to learn but I guess this is the behaviour most off.如果您发现一些其他方面非常渴望学习的东西,但我想这是最不合适的行为。

Hope it helps....希望能帮助到你....

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM