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

Flutter Localizations实时切换问题:基于Riverpod实现语言即时更新

即时切换Flutter语言(适配Riverpod)

核心思路

用Riverpod维护当前语言的可监听状态,切换语言时更新状态并同步缓存,同时让App的本地化配置响应状态变化,实现即时刷新。


1. 创建语言状态管理Provider

写一个LanguageNotifier处理语言状态的读取、切换和缓存逻辑,再通过StateNotifierProvider暴露给全局使用:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';

// 定义支持的语言列表
const supportedLocales = [
  Locale('zh', 'CN'),
  Locale('en', 'US'),
];

// 默认语言
const defaultLocale = Locale('zh', 'CN');

class LanguageNotifier extends StateNotifier<Locale> {
  LanguageNotifier() : super(defaultLocale) {
    _loadSavedLanguage();
  }

  // 从shared_preferences读取缓存语言
  Future<void> _loadSavedLanguage() async {
    final prefs = await SharedPreferences.getInstance();
    final savedLangCode = prefs.getString('selected_language_code');
    final savedCountryCode = prefs.getString('selected_country_code');
    if (savedLangCode != null && savedCountryCode != null) {
      state = Locale(savedLangCode, savedCountryCode);
    }
  }

  // 切换语言并保存到缓存
  Future<void> switchLanguage(Locale newLocale) async {
    state = newLocale;
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('selected_language_code', newLocale.languageCode);
    await prefs.setString('selected_country_code', newLocale.countryCode!);
  }
}

// 全局可访问的语言Provider
final languageProvider = StateNotifierProvider<LanguageNotifier, Locale>((ref) {
  return LanguageNotifier();
});

2. 修改main.dart,让MaterialApp响应语言状态

用Consumer包裹MaterialApp,监听语言Provider的状态变化,动态更新locale:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
// 导入上面的语言Provider文件

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

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

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // 实时获取当前语言状态
    final currentLocale = ref.watch(languageProvider);
    
    return MaterialApp(
      title: 'Language Demo',
      locale: currentLocale,
      supportedLocales: supportedLocales,
      localizationsDelegates: const [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        // 这里添加你的自定义本地化delegate
      ],
      home: const LanguageSelectorPage(),
    );
  }
}

3. 在selector.dart中实现切换逻辑

在语言选择页面,调用Provider的switchLanguage方法即可触发即时切换:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
// 导入语言Provider文件

class LanguageSelectorPage extends ConsumerWidget {
  const LanguageSelectorPage({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Scaffold(
      appBar: AppBar(title: const Text('选择语言')),
      body: ListView(
        children: [
          ListTile(
            title: const Text('中文'),
            onTap: () {
              ref.read(languageProvider.notifier).switchLanguage(const Locale('zh', 'CN'));
              Navigator.pop(context);
            },
          ),
          ListTile(
            title: const Text('English'),
            onTap: () {
              ref.read(languageProvider.notifier).switchLanguage(const Locale('en', 'US'));
              Navigator.pop(context);
            },
          ),
        ],
      ),
    );
  }
}

关键注意点

  • 确保你的本地化资源(比如intl包的arb文件)已正确配置,能匹配对应locale的文本
  • 自定义LocalizationsDelegate要能正确响应locale变化
  • 必须用ConsumerWidget或Consumer包裹依赖语言状态的部件,确保状态更新时自动重建

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 17:52:22