flutter开发实战-多语言flutter intl

flutter开发实战-多语言flutter intl

之前做的应用中有用到多语言,一直没有整理,这里整理一下多语言设置流程。
使用的是Android studio

一、flutter_intl 插件

使用Android studio安装flutter_intl 插件,更新或者安装flutter_intl 插件后会提示重新启动IDE。

如图所示:
在这里插入图片描述

二、使用fluter_intl插件

在Android Studio中菜单Tools找到flutter intl创建多语言配置。

在这里插入图片描述

创建后会在pubspec.yaml出现

flutter_intl:
  enabled: true

如图所示
在这里插入图片描述

在工程的lib会生成l10n与generated文件夹

l10n包含
intl_en.arb
intl_zn.arb

我们在intl_en.arb添加

{
    
    
'home': "Home",
}

在intl_zn.arb添加

{
    
    
'home': "首页",
}

三、编写代码

创建LocalModel

// 共享状态
class SessionChangeNotifier with ChangeNotifier {
    
    
  Session get session => Global.session;

  String? get getToken => Global.session.token;

  
  void notifyListeners() {
    
    
    // 保存Profile变更
    Global.saveProfile();

    //通知依赖的Widget更新
    super.notifyListeners();
  }
}

创建LocalModel

class LocaleModel extends SessionChangeNotifier {
    
    
  // 获取当前用户的APP语言配置Locale类,如果为null,则语言跟随系统语言
  Locale? getLocale() {
    
    
    if (session.locale == null) return null;
    var t = session.locale?.split("_");
    LoggerManager().debug("getLocale t:${
      
      t}");
    if (t != null && t.length == 2) {
    
    
      LoggerManager().debug("Locale t:${
      
      t}");
      return Locale(t[0], t[1]);
    }

    return null;
  }

  // 获取当前Locale的字符串表示
  String get locale => session.locale ?? "";

  // 用户改变APP语言后,通知依赖项更新,新语言会立即生效
  set locale(String locale) {
    
    
    LoggerManager().debug("locale:${
      
      locale}, profile.locale:${
      
      session.locale}");
    if (locale != session.locale) {
    
    
      session.locale = locale;
      notifyListeners();
    }
  }
}

在Main的入口中设置

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

  // This widget is the root of your application.
  
  Widget build(BuildContext context) {
    
    
    return MultiProvider(
      providers: providers,
      child: Consumer3<ThemeModel, LocaleModel, UserModel>(
        builder: (context, themeModel, localeModel, userModel, child) {
    
    
          return RefreshConfiguration(
            hideFooterWhenNotFull: false, //列表数据不满一页,不触发加载更多
            child: ScreenUtilInit(
              designSize: const Size(375.0, 667.0),
              minTextAdapt: true,
              splitScreenMode: true,
              builder: (context, child) {
    
    
                return child ??
                    buildMaterialApp(
                        context, localeModel, themeModel, userModel);
              },
              child:
                  buildMaterialApp(context, localeModel, themeModel, userModel),
            ),
          );
        },
      ),
    );
  }

  Widget buildMaterialApp(BuildContext context, LocaleModel localeModel,
      ThemeModel themeModel, UserModel userModel) {
    
    
    return MaterialApp(
      theme: ThemeData(
        fontFamily: "PingFang SC",
        primarySwatch: themeModel.theme,
      ),
      navigatorKey: OneContext().key,
      debugShowCheckedModeBanner: false,
      supportedLocales: S.delegate.supportedLocales,
      locale: localeModel.getLocale(),
      initialRoute: buildInitialRoute(
        appModel: Provider.of<AppModel>(context, listen: false),
        userModel: userModel,
      ),
      onGenerateRoute: RouterManager.generateRoute,
      navigatorObservers: buildObservers(),
      localizationsDelegates: const [
        S.delegate,
        RefreshLocalizations.delegate, //下拉刷新
        GlobalCupertinoLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate
      ],
      localeResolutionCallback: (_locale, supportedLocales) {
    
    
        if (localeModel.getLocale() != null) {
    
    
          //如果已经选定语言,则不跟随系统
          return localeModel.getLocale();
        } else {
    
    
          //跟随系统
          LoggerManager().debug("_locale:${
      
      _locale}");
          Locale locale;
          if (supportedLocales.contains(_locale)) {
    
    
            locale = _locale!;
          } else {
    
    
            //如果系统语言不是中文简体或美国英语,则默认使用美国英语
            locale = Locale('en', 'US');
          }
          return locale;
        }
      },
      builder: EasyLoading.init(builder: (BuildContext context, Widget? child) {
    
    
        return OneContext().builder(
          context,
          child,
          observers: buildObservers(),
        );
      }),
      home: buildGlobalGesture(context),
    );
  }

  Widget buildGlobalGesture(BuildContext context) {
    
    
    return GestureDetector(
      onTap: () {
    
    
        FocusScopeNode currentFocus = FocusScope.of(context);
        if (!currentFocus.hasPrimaryFocus &&
            currentFocus.focusedChild != null) {
    
    
          FocusManager.instance.primaryFocus?.unfocus();
          // 也可以使用如下方式隐藏键盘:
          // SystemChannels.textInput.invokeMethod('TextInput.hide');
        }
      },
    );
  }

  List<NavigatorObserver> buildObservers() {
    
    
    return [MyNavigatorObserver()];
  }

  String? buildInitialRoute(
      {
    
    required AppModel appModel, required UserModel userModel}) {
    
    
    String? initialRoute;
    // String? isAgree = localeModel.isAgree;
    String? isAgree = "1";
    if ("1" == isAgree) {
    
    
      if (userModel.isLogin) {
    
    
        initialRoute = RouterName.main;
      } else {
    
    
        initialRoute = RouterName.login;
      }
    } else {
    
    
      initialRoute = RouterName.agreement;
    }
    return initialRoute;
  }
}

之后我们可以在具体使用的地方这个配置的home。

return Scaffold(
      appBar: MyAppBar(
        label: S.of(context).home,
        isBackButton: false,
      ),
body:Container(),);

更换语言环境页面

class LanguagePage extends StatefulWidget {
    
    
  const LanguagePage({
    
    Key? key, this.arguments}) : super(key: key);

  final Object? arguments;

  
  State<LanguagePage> createState() => _LanguagePageState();
}

class _LanguagePageState extends State<LanguagePage> {
    
    
  
  Widget build(BuildContext context) {
    
    
    var color = Theme.of(context).primaryColor;
    var localeModel = Provider.of<LocaleModel>(context);
    Widget _buildLanguageItem(String lan, value) {
    
    
      LoggerManager().debug("_buildLanguageItem:${
      
      lan}, value:${
      
      value}");
      return SettingCheckItemWidget(
        title: lan,
        content: "",
        checkColor: color,
        isSelected: localeModel.locale == value,
        onPressed: () {
    
    
          // 此行代码会通知MaterialApp重新build
          localeModel.locale = value;
        },
      );
    }

    return Scaffold(
      appBar: MyAppBar(
        onPressed: () {
    
    
          navigatorBack();
        },
        label: S.of(context).language,
        isBackButton: true,
      ),
      body: ListView.builder(
        padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 10.0),
        addRepaintBoundaries: false,
        addAutomaticKeepAlives: false,
        itemCount: 3,
        itemBuilder: (context, index) {
    
    
          if (index == 0) {
    
    
            return _buildLanguageItem("中文简体", "zh_CN");
          }

          if (index == 1) {
    
    
            return _buildLanguageItem("English", "en_US");
          }

          if (index == 2) {
    
    
            return _buildLanguageItem(S.of(context).autoBySystem, null);
          }
          return Container();
        },
      ),
    );
  }

  void userEnterApp() {
    
    
    // 点击进入app
    NavigatorPageRouter.pushReplacementNamed(RouterName.main);
  }

  void navigatorBack() {
    
    
    NavigatorPageRouter.pop();
  }
}

四、小结

flutter开发实战-多语言flutter intl,使用的是Android studio,使用Provider通知语言变化时候展示对应的语言。

学习记录,每天不停进步。

猜你喜欢

转载自blog.csdn.net/gloryFlow/article/details/131638018