flutter ChangeNotifier页面间触发问题?

我在根实例上写了监听代码appModel!.addListener,在一个子页面中进行触发notifyListeners的操作,但addListener中的函数并未执行,为什么呀?

代码如下:
根页面

class MyApp extends StatefulWidget {
  @override
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  AppModel? appModel;

  @override
  void initState() {
    super.initState();
    Future.delayed(Duration.zero, () {
      appModel = Provider.of<AppModel>(context, listen: false);

      appModel!.addListener(() {
        print("change ${appModel!.localeCode}");//并未触发
      });
    });
  }
// This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    GlobalProperty.appContext = context;

    // print(ChinaDataArea.data);

    // print("asd:");
    // print(ChinaDataArea.codeToText("710110"));

    return GetMaterialApp(
      debugShowCheckedModeBanner: false,
      title: MConfig.NAME,
      theme: themeData,

      home: const SplashPage(),
      // home: const TabPage(),

      // routes: MRouter.routes,

      getPages: Pages.pages,

      navigatorKey: GlobalProperty.navigatorKey,

      locale: Locale(appModel == null ? "en" : appModel!.localeCode),

appModel

class AppModel with ChangeNotifier {
  IndexSetting indexSetting = IndexSetting();
  String localeCode = 'en';

  Future init() async {
    await LocalStorage.getItem('indexSetting').then((value) {
      setIndexSetting(value);
    });
    await LocalStorage.getItem('localeCode').then((value) {
      if (value != null) {
        setLocale(value);
      }
    });
  }

  setIndexSetting(data) {
    if (data == null) {
      indexSetting = IndexSetting();
      LocalStorage.remove("indexSetting");
    } else {
      indexSetting = IndexSetting.fromJson(data);
      LocalStorage.setItem("indexSetting", indexSetting);
    }
    notifyListeners(); //
  }

  setLocale(String code) {
    localeCode = code;
    LocalStorage.setItem("localeCode", code);
    notifyListeners(); //
  }
}

子页面

Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text("中文"),
              Radio(
                  value: 1,
                  groupValue: radio,
                  activeColor: ColorConst.primaryColor,
                  onChanged: (value) {
                    radio = 1;
                    appModel?.setLocale("zh");
                    setState(() {});
                  }),
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text("English"),
              Radio(
                  value: 2,
                  groupValue: radio,
                  activeColor: ColorConst.primaryColor,
                  onChanged: (value) {
                    radio = 2;
                    appModel?.setLocale("en");
                    setState(() {});
                  }),
            ],
          )
阅读 1k
avatarAI BotBETA

问题原因是在根页面中,监听代码appModel!.addListener在子页面中触发notifyListeners的操作之前执行了。在initState中的Future.delayed(Duration.zero, () { ... })将监听代码加入了微任务队列,而子页面中的操作是同步执行的,所以在子页面触发notifyListeners之前,监听代码已经执行完毕,导致没有执行。

解决方法是将监听代码放在子页面中的onChanged回调中,保证在触发notifyListeners之后再执行监听代码。

修改后的子页面代码如下:

Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: [
    Text("中文"),
    Radio(
      value: 1,
      groupValue: radio,
      activeColor: ColorConst.primaryColor,
      onChanged: (value) {
        radio = 1;
        appModel?.setLocale("zh");
        setState(() {});
        appModel!.addListener(() {
          print("change ${appModel!.localeCode}");
        });
      },
    ),
  ],
),
Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: [
    Text("English"),
    Radio(
      value: 2,
      groupValue: radio,
      activeColor: ColorConst.primaryColor,
      onChanged: (value) {
        radio = 2;
        appModel?.setLocale("en");
        setState(() {});
        appModel!.addListener(() {
          print("change ${appModel!.localeCode}");
        });
      },
    ),
  ],
)

这样修改后,当触发notifyListeners时,监听代码就会被执行。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题