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

Flutter应用语言切换仅生效一次问题求助

问题分析

你的语言切换仅能生效一次,核心问题在于:

  1. changeLanguage方法仅修改了静态变量APP_LANGUAGE,但没有触发本地化资源的重新加载,也没有通知UI层更新字符串内容。
  2. _selectedLanguage初始值硬编码为'French',未与AppSettings.APP_LANGUAGE同步,可能导致状态不一致。
  3. 切换语言后,没有让应用的上下文重新获取新的本地化配置,后续页面无法感知语言变化。
解决方案

步骤1:重构语言管理逻辑,添加状态通知

修改AppSettings,引入状态通知机制确保语言变化时能通知所有依赖的UI组件:

import 'package:flutter/foundation.dart';

class AppSettings extends ChangeNotifier {
  static String APP_LANGUAGE = 'French';
  static late AppStrings strings;

  // 初始化本地化字符串
  static void initStrings() {
    strings = APP_LANGUAGE == 'French' ? FrenchStrings() : EnglishStrings();
  }

  void changeLanguage(String newLanguage) {
    APP_LANGUAGE = newLanguage;
    // 更新本地化字符串实例
    strings = newLanguage == 'French' ? FrenchStrings() : EnglishStrings();
    // 通知所有监听者更新UI
    notifyListeners();
  }
}

步骤2:在根MaterialApp中集成状态管理

让根MaterialApp响应语言变化,使用ChangeNotifierProvider包裹并动态设置locale:

import 'package:provider/provider.dart';

void main() {
  AppSettings.initStrings();
  runApp(
    ChangeNotifierProvider(
      create: (context) => AppSettings(),
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appSettings = Provider.of<AppSettings>(context);
    return MaterialApp(
      locale: appSettings.APP_LANGUAGE == 'French' ? Locale('fr') : Locale('en'),
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: [
        Locale('en'),
        Locale('fr'),
      ],
      home: SettingView(),
    );
  }
}

步骤3:修改设置页面代码

同步初始语言状态,并通过Consumer监听语言变化自动重建UI:

class SettingViewState extends State<StatefulWidget> {
  late String _selectedLanguage;

  @override
  void initState() {
    super.initState();
    // 从AppSettings获取当前语言作为初始值
    _selectedLanguage = AppSettings.APP_LANGUAGE;
  }

  @override
  Widget build(BuildContext context) {
    print('SettingViewState - build');

    return Scaffold(
      drawer: NavDrawableWidget(),
      body: Consumer<AppSettings>(
        builder: (context, appSettings, child) {
          return Column(
            children: <Widget>[
              Center(
                child: Text('\n${AppSettings.strings.settingTitle}\n',
                  style: TextStyle(
                      fontSize: 18,
                      fontWeight: FontWeight.bold
                  ),
                ),
              ),
              Container(
                child: Card(
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(20),
                    side: BorderSide(color: Colors.black12, width: 2),
                  ),
                  child: ListTile(
                    title: Text(AppSettings.strings.languageTitle),
                    leading: Icon(Icons.language),
                    trailing: Theme(
                      data: Theme.of(context).copyWith(
                        canvasColor: Colors.blue[50],
                      ),
                      child: DropdownButton<String>(
                        value: _selectedLanguage,
                        items: [
                          DropdownMenuItem(
                            value: 'French',
                            child: Row(
                              children: <Widget>[
                                Image.asset(AppSettings.APP_FRENCH_FLAG,width: 30, height: 20,),
                                SizedBox(width: 10),
                                Text(AppSettings.strings.frenchTitle),
                              ],
                            ),
                          ),
                          DropdownMenuItem(
                            value: 'English',
                            child: Row(
                              children: <Widget>[
                                Image.asset(AppSettings.APP_ENGLISH_FLAG,width: 30, height: 20,),
                                SizedBox(width: 10),
                                Text(AppSettings.strings.englishTitle),
                              ],
                            ),
                          ),
                        ],
                        onChanged: (String? newValue) {
                          if (newValue == null) return;
                          setState(() {
                            _selectedLanguage = newValue;
                          });
                          // 通过Provider触发全局语言更新
                          Provider.of<AppSettings>(context, listen: false)
                              .changeLanguage(newValue);
                        },
                      ),
                    ),
                  ),
                ),
              ),
            ],
          );
        },
      ),
    );
  }
}

关键说明

  • 使用ChangeNotifier+Provider实现全局状态管理,确保语言变化时所有依赖页面都能自动重建。
  • changeLanguage方法中同步更新本地化字符串实例并通知UI刷新。
  • 设置页面初始化时同步全局语言状态,避免下拉选单与实际语言不一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 05:16:23