友情链接交换网站,中国最大的建材网站,农业品牌建设的基础是,安徽安庆网站建设公司多语言、主题切换之GetX库 前言正文一、配置项目二、模拟UI三、语言配置① 常量键② 语言配置文件③ 配置 四、持久化五、切换语言① my_home.dart② home.dart③ mine_controller.dart④ language_setting_controller.dart⑤ language_setting.dart⑥ mine.dart 六、切换主题①… 多语言、主题切换之GetX库 前言正文一、配置项目二、模拟UI三、语言配置① 常量键② 语言配置文件③ 配置 四、持久化五、切换语言① my_home.dart② home.dart③ mine_controller.dart④ language_setting_controller.dart⑤ language_setting.dart⑥ mine.dart 六、切换主题① 配置文件② 更改主题 七、源码 前言 关于GetX库前面我们讲述了状态管理的使用实际上GetX是非常强大的功能很多本篇文章中我们将介绍GetX的多语言切换和主题切换等功能。 正文 为了让你更清晰的知道这里我会结合实际开发中的一些操作方式和使用方式让你可以更好用在自己的项目上。
一、配置项目
首先创建项目 然后好之后打开pubspec.yaml文件在dependencies下面添加一个get:如下图所示 然后点击窗口上的Pub get已经依赖下载如下图所示 这里的依赖已经下载好了项目配置完成下面开始写代码。
二、模拟UI 做戏做全套为了让你感觉这是一个实际的项目我们就按照实际的项目的UI来做让你身临其境只不过缺点就是我需要写一部分与标题内容无关的UI代码见谅。 先说说我们要做什么首先我们需要做一个底部导航栏里面有两项内容首页和我的首页我们可以什么都不写而我的里面你可以直接将多语言的设置加在里面亦或者是再加一层进去弄一个设置页面在设置页面中设置多语言。 那么下面我们首先来写首页在lib下创建一个home文件夹然后里面创建一个home.dart代码如下所示
import package:flutter/material.dart;class Home extends StatelessWidget {const Home({Key? key}) : super(key: key);overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text(主页),),body: Center(child: Text(主页),));}
}代码非常简单就一个标题和文字内容下面我们创建另一个mine文件夹里面创建一个mine.dart代码如下所示
import package:flutter/material.dart;class Mine extends StatelessWidget {overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(我的),),body: Center(child: Text(我的),));}
}然后再创建一个my_home文件夹里面创建一个my_home_controller.dart
import package:get/get.dart;class MyHomeController extends GetxController {var currentIndex 0.obs;void changeIndex(int index) {currentIndex.value index;}
}这里面就是对于当前切换页面的记录和更新下面在my_home文件夹下创建一个my_home.dart里面装载我们前面写好的两个页面完成切换的工作代码如下所示
import package:flutter/material.dart;
import package:get/get.dart;import ../home/home.dart;
import ../mine/mine.dart;
import my_home_controller.dart;class MyHomePage extends StatelessWidget {MyHomePage({super.key});final controller Get.put(MyHomeController());overrideWidget build(BuildContext context) {return Scaffold(body: Obx(() {switch (controller.currentIndex.value) {case 0:return const Home();case 1:return Mine();default:return const Home();}}),bottomNavigationBar: Obx(() BottomNavigationBar(currentIndex: controller.currentIndex.value,onTap: (index) controller.changeIndex(index),items: const [BottomNavigationBarItem(icon: Icon(Icons.home), label: 首页),BottomNavigationBarItem(icon: Icon(Icons.person), label: 我的),])), );}
}上面属于GetX的常规使用然后就是在body中根据当前的item下标来确定显示什么内容底部的bottomNavigationBar中的内容也是如此onTap表示点击item是的indexitems里面就是对应的Item了目前来说我们没有使用多语言的只是做了UI最后一步就是修改main.dart装载我们写好的这个MyHomePage 代码如下所示
import package:flutter/material.dart;
import my_home/my_home.dart;void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});overrideWidget build(BuildContext context) {return MaterialApp(title: Flutter Demo,theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),useMaterial3: true,),home: MyHomePage(),);}
}下面我们运行一下 切换一下底部的导航栏没有问题的话我们就可以来写这个多语言切换了。
三、语言配置 在lib下创建一个language文件夹文件夹下创建一个local.dart文件里面代码如下所示
① 常量键
class Local {static const String home home;//首页static const String mine mine;//我的static const String languageSetting languageSet;//多语言设置static const String followerSystemLanguage followerSystemLanguage;//跟随系统语言static const String simplifiedChinese simplifiedChinese;//简体中文
}这里代码很简单就是一些常量用来确定我们需要引用的文字资源键。
② 语言配置文件 下面我们在language目录下创建一个messages.dart文件里面代码如下所示
import package:get/get.dart;
import local.dart;class Messages extends Translations {overrideMapString, MapString, String get keys {zh_CN: {Local.home: 主页,Local.mine: 我的,Local.languageSetting: 多语言设置,Local.followerSystemLanguage: 跟随系统语言,Local.simplifiedChinese: 简体中文,},en_US: {Local.home: Home,Local.mine: Mine,Local.languageSetting: Multilingual setup,Local.followerSystemLanguage: Follower system Language,Local.simplifiedChinese: Simplified Chinese,},};
}通过使用继承Get的Translations 进行键值的切换zh_CN是中文en_US是英文里面通过键获取对应的值那么这一部分我们就写好了后续如果有新的字符添加进来就依葫芦画瓢。
③ 配置
最后一步就是配置进去了打开main.dart文件修改如下所示
import package:flutter/material.dart;
import language/messages.dart;
import my_home/my_home.dart;
import package:get/get.dart;void main() async {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});overrideWidget build(BuildContext context) {return GetMaterialApp(title: Flutter Demo,translations: Messages(),locale: Get.deviceLocale,fallbackLocale: Locale(zh, CN),theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),useMaterial3: true,),home: MyHomePage(),);}
}这里首先将MaterialApp改成了GetMaterialApp然后配置相关的属性值如下所示 translations: Messages(),locale: Get.deviceLocale,fallbackLocale: Locale(zh, CN),注意这里的locale: Get.deviceLocale,这表示当前的语言环境是跟随系统语言的后面这里还需要更改的因为我们需要做持久化假如我们支持3钟设置跟随系统语言、中文、英文。当我们第一次打开App时默认是跟随系统语言而我们切换为英文之后再重新打开App发现没有变化这是因为我们没有更改这个locale的属性值因此就涉及到持久化存储了你想到了什么呢我想到了Android的SP之前我们介绍过Hive这里我也将使用Hive。
四、持久化
下面我们首先在pubspec.yaml中增加配置如下所示 然后点击Pub get下载依赖。下载好之后在lib下创建一个app_box.dart文件代码如下所示
import package:hive_flutter/hive_flutter.dart;class AppBox {static final AppBox shared AppBox();// 声明盒子final _box Hive.box(appBox);// 语言int get language _box.get(language) ?? 0;set language(int value) _box.put(language, value);// 主题int get theme _box.get(theme) ?? 0;set theme(int value) _box.put(theme, value);
}是不是感觉代码很熟悉呢下面我们就要配置一下这个appBox否则会报错在main.dart中配置代码如下所示
import package:flutter/material.dart;
import package:hive_flutter/hive_flutter.dart;
import package:study_language_theme/app_box.dart;
import language/messages.dart;
import my_home/my_home.dart;
import package:get/get.dart;void main() async {await Hive.initFlutter();await Hive.openBox(appBox);runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Locale? getLocale() {Locale? appLocale;switch (AppBox.shared.language) {case 0: //跟隨系統appLocale Get.deviceLocale;break;case 1: //简体中文appLocale const Locale(zh, CN);break;case 2: //EnglishappLocale const Locale(en, US);break;default:appLocale Get.deviceLocale;break;}return appLocale;}overrideWidget build(BuildContext context) {return GetMaterialApp(title: Flutter Demo,translations: Messages(),locale: getLocale(),fallbackLocale: Locale(zh, CN),theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),useMaterial3: true,),home: MyHomePage(),);}
}首先在main()函数中进行Hive的初始化配置和盒子的配置同时增加了一个getLocale()函数在里面就根据键获取对应的语言设置下标根据下标设置语言模式最后再改变locale: getLocale(),这样就完成了持久化的处理但是还没有全部完成这里是取值我们还需要存值存值在哪里就在设置语言哪里下面来写这一步。
五、切换语言
① my_home.dart 现在为了是我们的切换语言生效在我们之前直接使用字符串的地方现在就需要更改为Local中的键了首先我们修改一下my_home.dart中的代码如下图所示 这里就将“首页”改成了Local.home.tr这里的tr就是用于切换语言后自动改变的记得要加上去通过如果加了tr则对应的外部组件不能使用const关键字请注意。
② home.dart
下面再改动一下home.dart ③ mine_controller.dart 最后我们修改mine在此之前先在mine中增加一个mine_controller.dart代码如下
import package:get/get.dart;
import package:study_language_theme/app_box.dart;
import package:study_language_theme/language/local.dart;
import package:flutter/widgets.dart;class MineController extends GetxController with WidgetsBindingObserver {final languageStr Local.followerSystemLanguage.tr.obs;RxInt languageIndex 0.obs;overridevoid onInit() {super.onInit();WidgetsBinding.instance.addObserver(this);getLanguage();}overrideonClose() {super.onClose();WidgetsBinding.instance.removeObserver(this);}overridevoid didChangeAppLifecycleState(AppLifecycleState state) {super.didChangeAppLifecycleState(state);getLanguage();}//获取语言void getLanguage() {switch (AppBox.shared.language) {case 0:languageStr.value Local.followerSystemLanguage.tr;break;case 1:languageStr.value Local.simplifiedChinese.tr;break;case 2:languageStr.value English;break;default:languageStr.value Local.followerSystemLanguage.tr;break;}}//切换语言void changeLanguage(int index) {languageIndex.value index;}
}这里通过Getx处理页面显示的语言设置项目切换语言和获取语言。
④ language_setting_controller.dart 在lib下新建一个settings文件夹里面创建一个用于切换语言的language_setting_controller.dart代码如下所示
import package:flutter/widgets.dart;
import package:get/get.dart;
import package:study_language_theme/app_box.dart;import ../language/local.dart;class LanguageSettingsController extends GetxController {final currentLanguageIndex 0.obs;ListString languageList [Local.followerSystemLanguage.tr,简体中文,English,];overridevoid onInit() {super.onInit();currentLanguageIndex.value AppBox.shared.language;}///切换语言void changeLanguage(int languageIndex) {Locale? appLocale;switch (languageIndex) {case 0: //跟隨系統appLocale Get.deviceLocale;break;case 1: //简体中文appLocale const Locale(zh, CN);break;case 2: //EnglishappLocale const Locale(en, US);break;default:appLocale Get.deviceLocale;break;}//保存到本地AppBox.shared.language languageIndex;Get.updateLocale(appLocale!);}
}在changeLanguage()函数中保存切换的语言下标然后更新语言配置。
⑤ language_setting.dart
在settings下创建一个language_setting.dart代码如下所示
import package:flutter/cupertino.dart;
import package:flutter/material.dart;
import package:get/get.dart;
import package:study_language_theme/language/local.dart;import language_setting_controller.dart;///语言设置页面
class LanguageSettingPage extends StatelessWidget {LanguageSettingPage({Key? key}) : super(key: key);final controller Get.put(LanguageSettingsController());overrideWidget build(BuildContext context) {return Scaffold(backgroundColor: const Color(0xFFF7F9FF),appBar: AppBar(centerTitle: true,title: Text(Local.languageSetting.tr,style: const TextStyle(color: Colors.black),),backgroundColor: Colors.white,leading: const CupertinoNavigationBarBackButton(color: Colors.black)),body: Container(padding: const EdgeInsets.only(top: 10,),child: ListView.separated(itemBuilder: (context, index) {return Obx(() Container(padding: const EdgeInsets.only(left: 16, right: 16),color: Colors.white,height: 50,child: InkWell(onTap: () {controller.changeLanguage(index);Get.back(result: index);},child: Row(children: [Expanded(child: Text(controller.languageList[index])),Visibility(visible: controller.currentLanguageIndex.value index,child: const Icon(Icons.check_rounded,color: Colors.blue))],),),));},separatorBuilder: (context, index) {return Container(height: 2,color: Colors.white70,);},itemCount: controller.languageList.length),),);}
}在这个语言设置页面中主要的内容就是一个列表用于点击Item切换语言项切换之后返回上一个页面同时传值过去
⑥ mine.dart
最后我们改动一下mine.dart如下所示
import package:flutter/material.dart;
import package:get/get.dart;
import package:study_language_theme/language/local.dart;
import package:study_language_theme/mine/mine_controller.dart;import ../settings/language_setting.dart;class Mine extends StatelessWidget {Mine({super.key});final controller Get.put(MineController());overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(Local.mine.tr),),body: Container(color: Colors.white54,padding: const EdgeInsets.only(top: 20),child: Container(padding: const EdgeInsets.all(16),color: Colors.white,child: Row(children: [Expanded(child: Text(Local.languageSetting.tr),),InkWell(onTap: () {Get.to(() LanguageSettingPage())?.then((value) {controller.getLanguage();});},child: Row(children: [Text(controller.languageStr.value, style: const TextStyle(fontSize: 12),),const Icon(Icons.chevron_right)],),)],),)));}
}到此为止我们的代码就改的差不多了下面就可以运行了效果如下图所示
六、切换主题 切换主题相对来说简单很多。
① 配置文件
首先我们在lib下创建一个custom_theme.dart里面代码如下
import package:flutter/material.dart;
import package:flutter/services.dart;///浅色模式
ThemeData lightTheme ThemeData.light().copyWith(primaryColor: Colors.blue,splashColor: Colors.white12,appBarTheme: AppBarTheme(systemOverlayStyle: SystemUiOverlayStyle.dark,elevation: 0,backgroundColor: ThemeData.light().scaffoldBackgroundColor,iconTheme: const IconThemeData(color: Colors.black),),dividerColor: Colors.white38,scaffoldBackgroundColor: ThemeData.light().scaffoldBackgroundColor,backgroundColor: Colors.white,iconTheme: const IconThemeData(color: Colors.black,),bottomNavigationBarTheme: const BottomNavigationBarThemeData(selectedItemColor: Colors.black,unselectedItemColor: Colors.grey),
);///深色模式
ThemeData darkTheme ThemeData.dark().copyWith(appBarTheme: AppBarTheme(systemOverlayStyle: SystemUiOverlayStyle.light,elevation: 0,backgroundColor: ThemeData.dark().scaffoldBackgroundColor,iconTheme: const IconThemeData(color: Colors.white),),dividerColor: Colors.black38,scaffoldBackgroundColor: ThemeData.dark().scaffoldBackgroundColor,backgroundColor: Colors.black,iconTheme: const IconThemeData(color: Colors.white,),bottomNavigationBarTheme: const BottomNavigationBarThemeData(selectedItemColor: Colors.white,unselectedItemColor: Colors.white24),
);
这里面定义了浅色模式和深色模式两种这也是现在App大部分会做的功能里面定义了标题栏、脚手架背景、图标主题、底部导航栏在不同模式下的颜色设置。
然后我们去修改main.dart中的内容 overrideWidget build(BuildContext context) {return GetMaterialApp(title: Flutter Demo,translations: Messages(),locale: getLocale(),fallbackLocale: Locale(zh, CN),theme: lightTheme,darkTheme: darkTheme,themeMode: AppBox.shared.theme 0? MediaQuery.of(context).platformBrightness Brightness.dark ? ThemeMode.dark : ThemeMode.light: AppBox.shared.theme 1? ThemeMode.light: ThemeMode.dark,home: MyHomePage(),);}主要是修改themeMode的值记得导包import custom_theme.dart;。
② 更改主题 然后在settings下创建对应更换主题页面首先我们创建一个theme_setting_controller.dart里面代码如下所示
import package:flutter/material.dart;
import package:get/get.dart;
import package:study_language_theme/app_box.dart;
import package:study_language_theme/custom_theme.dart;import ../language/local.dart;class ThemeSettingsController extends GetxController {final currentThemeIndex 0.obs;ListString themeList [Local.followerSystemTheme.tr,Local.lightMode.tr,Local.darkMode.tr,];overridevoid onInit() {super.onInit();currentThemeIndex.value AppBox.shared.theme;}///切换主题void changeTheme(BuildContext context, int themeIndex) {ThemeData themeData;switch (themeIndex) {case 0: //跟隨系統themeData MediaQuery.of(context).platformBrightness Brightness.dark ? darkTheme : lightTheme;break;case 1: //浅色模式themeData lightTheme;break;case 2: //深色模式themeData darkTheme;break;default:themeData MediaQuery.of(context).platformBrightness Brightness.dark ? darkTheme : lightTheme;break;}//保存到本地AppBox.shared.theme themeIndex;Get.changeTheme(themeData);}
} 和切换语言没有什么太大的区别同样最后使用 Get.changeTheme切换主题下面我们要写页面了在settings下创建theme_setting.dart里面代码如下所示
import package:flutter/material.dart;
import package:get/get.dart;
import package:study_language_theme/language/local.dart;import theme_setting_controller.dart;///主题设置页面
class ThemeSettingPage extends StatelessWidget {ThemeSettingPage({Key? key}) : super(key: key);final controller Get.put(ThemeSettingsController());overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(centerTitle: true,title: Text(Local.themeSetting.tr,),),body: Container(padding: const EdgeInsets.only(top: 10,),child: ListView.separated(itemBuilder: (context, index) {return Obx(() Container(padding: const EdgeInsets.only(left: 16, right: 16),height: 50,child: InkWell(onTap: () {controller.changeTheme(context,index);Get.back(result: index);},child: Row(children: [Expanded(child: Text(controller.themeList[index])),Visibility(visible: controller.currentThemeIndex.value index,child: const Icon(Icons.check_rounded,color: Colors.blue))],),),));},separatorBuilder: (context, index) {return const Divider();},itemCount: controller.themeList.length),),);}
} 这里的代码和之前的设置语言页面差不多区别就是我将所有的背景颜色都去掉了这样才能时候切换后的效果切换之前用到背景颜色的地方你都需要更改一下最后我们修改一下mine_controller.dart和mine.dart的代码先是mine_controller.dart代码如下所示
import package:get/get.dart;
import package:study_language_theme/app_box.dart;
import package:study_language_theme/language/local.dart;
import package:flutter/widgets.dart;class MineController extends GetxController with WidgetsBindingObserver {final languageStr Local.followerSystemLanguage.tr.obs;final themeStr Local.followerSystemTheme.tr.obs;overridevoid onInit() {super.onInit();WidgetsBinding.instance.addObserver(this);getLanguage();getTheme();}overrideonClose() {super.onClose();WidgetsBinding.instance.removeObserver(this);}overridevoid didChangeAppLifecycleState(AppLifecycleState state) {super.didChangeAppLifecycleState(state);getLanguage();}overridevoid didChangePlatformBrightness() {super.didChangePlatformBrightness();getTheme();}//获取语言void getLanguage() {switch (AppBox.shared.language) {case 0:languageStr.value Local.followerSystemLanguage.tr;break;case 1:languageStr.value Local.simplifiedChinese.tr;break;case 2:languageStr.value English;break;default:languageStr.value Local.followerSystemLanguage.tr;break;}}//获取主题void getTheme() {switch (AppBox.shared.theme) {case 0:themeStr.value Local.followerSystemTheme.tr;break;case 1:themeStr.value Local.lightMode.tr;break;case 2:themeStr.value Local.darkMode.tr;break;default:themeStr.value Local.followerSystemTheme.tr;break;}}
}相比之前增加了获取最新主题的文字描述切换主题后改变文字描述然后修改mine_controller.dart代码如下所示
import package:flutter/material.dart;
import package:get/get.dart;
import package:study_language_theme/language/local.dart;
import package:study_language_theme/mine/mine_controller.dart;
import package:study_language_theme/settings/theme_setting.dart;import ../settings/language_setting.dart;class Mine extends StatelessWidget {Mine({super.key});final controller Get.put(MineController());overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(Local.mine.tr),),body: Container(padding: const EdgeInsets.only(top: 20),child: Container(padding: const EdgeInsets.all(16),child: Column(children: [Row(children: [Expanded(child: Text(Local.languageSetting.tr),),InkWell(onTap: () {Get.to(() LanguageSettingPage())?.then((value) {controller.getLanguage();});},child: Row(children: [Obx(() Text(controller.languageStr.value, style: const TextStyle(fontSize: 12),)),const Icon(Icons.chevron_right)],),)],),SizedBox(height: 10,),Row(children: [Expanded(child: Text(Local.themeSetting.tr),),InkWell(onTap: () {Get.to(() ThemeSettingPage())?.then((value) {controller.getTheme();});},child: Row(children: [Obx(() Text(controller.themeStr.value, style: const TextStyle(fontSize: 12),),),const Icon(Icons.chevron_right)],),)],)],),)));}
}到这里为止我们就修改好了现在我们运行一下看看效果。 本文就写到这里了如果你发现文章代码达不到效果图的效果那么应该是没有贴完整那么你可以通过源码去进行对照修改。
七、源码
源码地址study_language_theme