首页 > 解决方案 > 由于当前屏幕上的更新,防止 Flutter Provider 重建前一屏幕中的小部件

问题描述

我仍然在寻找更好的陈述来在这里充分表达我的问题,所以在这里详细说明

使用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();
  }
}

这是性能选项卡屏幕截图

标签: androidflutterdart

解决方案


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


推荐阅读