由于当前屏幕上的更新,阻止Flutter Provider重建先前屏幕上的小部件

时间:2019-08-31 18:07:04

标签: android flutter dart

我仍在寻找更好的陈述来在这里完整表达我的问题,所以这里是详细的

使用Provider允许在会影响它们的更改上重建小部件。太好了!


假设在主屏幕上(例如HomePage),我通过开关在黑暗与明亮之间切换主题。这些小部件将在主屏幕上重建。 现在,我导航到其他屏幕(例如NextScreen)。

这里有一个按钮允许我再次切换主题。我切换主题,然后重建当前屏幕(NextScreen)上的小部件。但是Android Studio上的Flutter Performance标签显示,前一个屏幕(HomePage)上的小部件也已重绘。


所以,我的问题是

  1. 为什么会这样?
  2. 有没有一种方法可以防止重建不在当前屏幕上的窗口小部件,而仅当我们返回特定屏幕时才重建它们?

我的代码是一个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

0 个答案:

没有答案