android - 由于当前屏幕上的更新,防止 Flutter Provider 重建前一屏幕中的小部件

标签 android flutter dart

我仍然在寻找更好的陈述来在这里充分表达我的问题,所以在这里详细说明
使用 Provider允许在会影响它们的更改上重建小部件。伟大的!。

假设在主屏幕上(比如 HomePage )我通过开关在暗和亮之间切换主题。小部件在主屏幕上重建。
现在我导航到其他屏幕(比如 NextScreen )。
这里有一个按钮可以让我再次切换主题。我切换主题,然后重建当前屏幕上的小部件(即 NextScreen )。但 Android Studio 上的 Flutter Performance 选项卡显示前一屏 (HomePage) 上的小部件也被重绘。

所以,我的问题是

  • 为什么会这样?
  • 有没有办法防止重建不在当前屏幕上的小部件,并且仅在我们返回特定屏幕时重建它们?

  • 我的代码是 90 行的简单示例
    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return ChangeNotifierProvider<ThemeState>(
          child: MaterialApp(
            home: HomePage(),
            routes: {
              "next": (context) => NextScreen(),
            },
          ),
          builder: (BuildContext context) => ThemeState(),
        );
      }
    }
    
    class HomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Consumer<ThemeState>(builder: (BuildContext context, ThemeState value, Widget child) {
          return Theme(
            data: value.getTheme(),
            child: Scaffold(
              appBar: AppBar(),
              body: Column(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  SwitchListTile(
                    title: Text("Enable dark mode"),
                    value: value.isDarkModeOn,
                    onChanged: (_) => value.toggleTheme(),
                  ),
                ],
              ),
              floatingActionButton: FloatingActionButton(
                onPressed: () => Navigator.pushNamed(context, "next"),
                child: Icon(Icons.navigate_next),
              ),
            ),
          );
        });
      }
    }
    
    class NextScreen extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Consumer<ThemeState>(
          builder: (context, value, child) {
            return Theme(
              child: Scaffold(
                appBar: AppBar(
                  title: Text("Next Screen"),
                ),
                body: Center(
                  child: RaisedButton(
                    onPressed: () => value.toggleTheme(),
                    child: Text("Toggle theme"),
                  ),
                ),
              ),
              data: value.getTheme(),
            );
          },
        );
      }
    }
    
    class ThemeState with ChangeNotifier {
      bool isDark = true;
      static ThemeData darkTheme = ThemeData.dark();
      static ThemeData lightTheme = ThemeData.light();
    
      ThemeData _currentTheme = darkTheme;
    
      ThemeData getTheme() => _currentTheme;
    
      get isDarkModeOn => isDark;
    
      toggleTheme() {
        _currentTheme = isDark ? lightTheme : darkTheme;
    
        isDark = !isDark;
        notifyListeners();
      }
    }
    

    Here is the Performance tab screenshot

    最佳答案

    由于您的消费者提供者小部件是其他小部件的父级,因此当提供者在切换时更新时,消费者子小部件也会更新。

    关于android - 由于当前屏幕上的更新,防止 Flutter Provider 重建前一屏幕中的小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57740510/

    相关文章:

    design-patterns - 如何定义抽象小部件?

    dart - Flutter:忽略小部件上的触摸事件

    java - 如何缩放 .JPEG 以适应位于 GridView 中的按钮?

    flutter - Dart:检查对象是否实现接口(interface)

    java - 无法从 Handler 类型对非静态方法 sendEmptyMessage(int) 进行静态引用

    ios - 未调用 Flutter Firebase Messaging iOS 处理程序

    dart - 装饰器数据绑定(bind)

    dart - _internal 的语义是什么?

    android - 为 Android 翻译 XML 字符串

    java - 我的应用程序使用相机不记录纬度和经度(文件元数据)