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

如何通过Flutter_localizations与Bloc实现Flutter应用语言的永久切换?

解决方案:实现Flutter多语言持久化(基于Bloc和flutter_localizations)

先直接解决你的核心问题:关闭重启后语言重置,是因为当前代码没有持久化用户选择的语言。下面是完整的修改方案,同时解答你的疑问。


核心修改思路

  1. 用SharedPreferences存储用户选择的语言(轻量级键值存储,适合这类简单配置)
  2. 应用启动时优先读取存储的语言,没有则用默认英文
  3. 修改Bloc逻辑,切换语言时同步保存到本地存储

修改后的完整代码

首先确保在pubspec.yaml中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  bloc: ^8.1.0
  flutter_bloc: ^8.1.0
  shared_preferences: ^2.2.0

1. 初始化逻辑(main函数)

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
// 导入你的AppLocalizations类

void main() async {
  // 必须提前初始化Flutter绑定,才能在runApp前执行异步操作
  WidgetsFlutterBinding.ensureInitialized();
  
  // 读取本地存储的语言配置
  final prefs = await SharedPreferences.getInstance();
  final savedLangCode = prefs.getString('selected_language');
  
  // 设置初始语言:有存储值用存储值,无则默认英文
  Locale initialLocale = savedLangCode != null 
      ? Locale(savedLangCode, '') 
      : const Locale('en', '');

  runApp(MyApp(initialLocale: initialLocale));
}

2. MyApp组件

class MyApp extends StatelessWidget {
  final Locale initialLocale;

  const MyApp({Key? key, required this.initialLocale}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => LanguageCubit(initialLocale),
      child: BlocBuilder<LanguageCubit, Locale>(builder: (context, lang) {
        return MaterialApp(
          locale: lang,
          title: 'Localizations Sample App',
          localizationsDelegates: const [
            AppLocalizations.delegate,
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
            GlobalCupertinoLocalizations.delegate,
          ],
          supportedLocales: const [
            Locale('en', ''),
            Locale('es', ''),
            Locale('tr', ''),
            Locale('it', ''),
          ],
          home: const Home(),
        );
      }),
    );
  }
}

3. LanguageCubit(加入持久化逻辑)

class LanguageCubit extends Cubit<Locale> {
  LanguageCubit(Locale initialLocale) : super(initialLocale);

  static final _languageEn = const Locale('en', '');
  static final _languageEs = const Locale('es', '');
  static final _languageTr = const Locale('tr', '');
  static final _languageIt = const Locale('it', '');

  // 切换英文并保存
  Future<void> changeLangEn() async {
    await _saveLanguage('en');
    emit(_languageEn);
  }

  // 切换西班牙文并保存
  Future<void> changeLangEs() async {
    await _saveLanguage('es');
    emit(_languageEs);
  }

  // 切换土耳其文并保存
  Future<void> changeLangTr() async {
    await _saveLanguage('tr');
    emit(_languageTr);
  }

  // 切换意大利文并保存
  Future<void> changeLangIt() async {
    await _saveLanguage('it');
    emit(_languageIt);
  }

  // 私有方法:保存语言到本地存储
  Future<void> _saveLanguage(String langCode) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('selected_language', langCode);
  }
}

4. Home页面(扩展多语言切换按钮)

class Home extends StatelessWidget {
  const Home({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          color: Colors.amberAccent,
          width: 200,
          height: 300,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(AppLocalizations.of(context).helloWorld, style: const TextStyle(fontSize: 18)),
              const Divider(height: 20),
              TextButton(
                onPressed: () => context.read<LanguageCubit>().changeLangEn(),
                child: const Text('English')),
              TextButton(
                onPressed: () => context.read<LanguageCubit>().changeLangEs(),
                child: const Text('Español')),
              TextButton(
                onPressed: () => context.read<LanguageCubit>().changeLangTr(),
                child: const Text('Türkçe')),
              TextButton(
                onPressed: () => context.read<LanguageCubit>().changeLangIt(),
                child: const Text('Italiano')),
            ],
          ),
        ),
      ),
    );
  }
}

你的疑问解答

1. 是否需要将选中的语言存储到数据库等存储介质?

不需要。语言选择是单个字符串的简单配置,用SharedPreferences完全足够——它是Flutter官方提供的轻量级键值对存储,操作简单、性能好,适合保存这类用户偏好设置。只有当你需要存储复杂结构化数据时,才考虑用Hive、SQFlite等数据库。

2. Flutter_localizations是否提供了简便的实现方式?

不提供。flutter_localizations的核心职责是加载本地化资源、适配系统语言规则、提供国际化组件支持,它并不包含持久化用户选择语言的逻辑。持久化需要我们结合本地存储方案(比如上面用的SharedPreferences)自行实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 15:52:39