You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从任意位置强制Flutter Widget重建?

解决方案:强制重建MaterialApp.builder的实现方式

要实现调用lockApp()后触发MaterialApp.builder重建,核心是让状态变化能通知到Widget树,触发目标Widget的重新构建。以下是两种可行的实现方式:

方式一:使用ChangeNotifier(推荐,可扩展)

首先改造SecurityModel,让它继承ChangeNotifier,具备状态通知能力:

class SecurityModel extends ChangeNotifier {
  bool appIsLocked = false;

  void lockApp() {
    appIsLocked = true;
    notifyListeners(); // 通知所有监听者状态已变更
  }
}

然后在MaterialApp外层包裹ListenableBuilder,监听SecurityModel的状态变化,一旦收到通知就会重建内部的MaterialApp,进而触发builder重新执行:

void main() {
  final securityModel = SecurityModel();
  runApp(
    // 全局提供SecurityModel,方便其他页面调用lockApp
    ChangeNotifierProvider.value(
      value: securityModel,
      child: MyApp(securityModel: securityModel),
    ),
  );
}

class MyApp extends StatelessWidget {
  final SecurityModel securityModel;

  const MyApp({super.key, required this.securityModel});

  @override
  Widget build(BuildContext context) {
    return ListenableBuilder(
      listenable: securityModel,
      builder: (context, child) {
        return MaterialApp(
          builder: (context, child) {
            if (securityModel.appIsLocked) {
              return const LockScreen();
            }
            return child!;
          },
          home: const MainScreen(),
          routes: {
            '/page1': (context) => const Page1Screen(),
            '/page2': (context) => const Page2Screen(),
          },
        );
      },
    );
  }
}

在代码任意位置,只要能获取到SecurityModel的实例,调用lockApp()就能触发MaterialApp.builder重建,切换到LockScreen。

方式二:使用ValueNotifier(轻量快捷)

如果不需要复杂的状态管理,用ValueNotifier可以更简洁地实现:

// 全局定义状态通知器
final ValueNotifier<bool> appIsLockedNotifier = ValueNotifier(false);

// 任意位置调用此方法锁定应用
void lockApp() {
  appIsLockedNotifier.value = true;
}

然后用ValueListenableBuilder包裹MaterialApp:

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<bool>(
      valueListenable: appIsLockedNotifier,
      builder: (context, isLocked, child) {
        return MaterialApp(
          builder: (context, child) {
            if (isLocked) {
              return const LockScreen();
            }
            return child!;
          },
          home: const MainScreen(),
          routes: {
            '/page1': (context) => const Page1Screen(),
            '/page2': (context) => const Page2Screen(),
          },
        );
      },
    );
  }
}

原理说明

Flutter的Widget只会在自身状态变化或父Widget重建时刷新。你原来的SecurityModel是普通类,状态变更无法通知到Widget树,所以MaterialApp.builder不会自动重建。通过ChangeNotifier或ValueNotifier,我们让状态变更具备了通知能力,外层的ListenableBuilder/ValueListenableBuilder收到通知后会重建内部的MaterialApp,从而触发builder重新执行,实现切换到LockScreen的效果。

内容的提问来源于stack exchange,提问作者Magnus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 15:02:47