FlutteDemo第一天(实现自定义本地中英文切换功能)

效果图,代码注释全。

在这里插入图片描述在这里插入图片描述

首先

dependencies:
 flutter:
   sdk: flutter
 cupertino_icons: ^1.0.2
 flutter_localizations:
   sdk: flutter
 shared_preferences: ^2.2.0

dev_dependencies:
 flutter_test:
   sdk: flutter

这是一个pubspec.yaml文件中的代码示例,用于声明Flutter应用程序所需的依赖项。
首先,flutter_localizations是一个Flutter SDK提供的本地化库,用于本地化和国际化应用程序。通过将它添加到dependencies中,您可以在应用程序中使用与设备语言匹配的本地化资源。
而shared_preferences是一个用于持久化存储数据的Flutter插件。它允许您在应用程序内存储和检索键值对,并且这些数据将在应用程序退出后仍然保留。

第一步:在根目录lib下新建文件夹l10n,文件内容如下图所示,其中 en.dart用于存放英文文字,zh.dart用于存放中文文字,messages.dart里面的类用于获取当前语言环境下的翻译文本。

在这里插入图片描述

en.dart里面的代码如

在这里插入图片描述

zh.dart里面的代码如

在这里插入图片描述

messages.dart里面的代码

import 'package:flutter/material.dart';
import 'package:management_flutter/l10n/locales/en.dart' as en;
import 'package:management_flutter/l10n/locales/zh.dart' as zh;

//AppLocalizations 类用于表示应用程序的本地化资源。每个语言环境都有一个对应的 AppLocalizations 实例,用于获取该语言下的翻译文本。
class AppLocalizations {
  final Locale locale;
//构造函数用于创建 AppLocalizations 实例,并传入当前的语言环境。of 方法用于从给定的上下文中获取 AppLocalizations 实例。
  AppLocalizations(this.locale);

  static AppLocalizations? of(BuildContext context) {
    return Localizations.of<AppLocalizations>(context, AppLocalizations);
  }
//_localizedValues 是一个字典,它保存着不同语言环境下的翻译文本。其中 'en' 和 'zh' 分别对应英文和中文的翻译资源,en.dart 和 zh.dart 文件分别定义了这些翻译文本。
  static final Map<String, Map<String, String>> _localizedValues = {
    'en': en.en,
    'zh': zh.zh,
  };
//operator [] 方法用于获取指定键(key)对应的翻译文本。它通过检索 _localizedValues 字典中当前语言环境的翻译文本,并返回对应的值。
  String operator [](String key) {
    return _localizedValues[locale.languageCode]![key]!;
  }
}
//AppLocalizationsDelegate 类是一个 LocalizationsDelegate 的子类,用于提供本地化资源。
class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
  const AppLocalizationsDelegate();
//isSupported 方法用于检查给定的语言环境是否受支持。在这里,我们只支持英文('en')和中文('zh')两种语言环境。
  @override
  bool isSupported(Locale locale) {
    return ['en', 'zh'].contains(locale.languageCode);
  }
//load 方法用于异步加载指定语言环境的本地化资源。在这里,我们使用 Future.delayed 方法模拟异步加载过程,并创建一个 AppLocalizations 实例。
  @override
  Future<AppLocalizations> load(Locale locale) async {
    return AppLocalizations(locale);
  }
//shouldReload 方法用于判断是否需要重新加载本地化资源。在这里,我们始终返回 false,表示不需要重新加载。
  @override
  bool shouldReload(AppLocalizationsDelegate old) {
    return false;
  }
}

第二步:入口文件main.dart修改

import 'package:flutter/material.dart';
import 'package:management_flutter/Login/LoginPage.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'l10n/messages.dart';

void main() {
  runApp(const MyApp());
}

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

  //setLocale 方法用于从应用的任何位置切换语言环境。它通过找到最近的 _MyAppState 实例,并调用其 setLocale 方法来实现切换语言功能。
  static void setLocale(BuildContext context, Locale newLocale) {
    _MyAppState state = context.findAncestorStateOfType<_MyAppState>()!;
    state.setLocale(newLocale);
  }

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Locale _locale = const Locale('en', ''); // 默认语言为英文
//_loadLocaleFromPreferences 方法从 SharedPreferences 中加载用户偏好设置的语言环境。如果存在保存的语言代码,就将其更新到 _locale 变量中。
  Future<void> _loadLocaleFromPreferences() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String? languageCode = prefs.getString('languageCode');
    if (languageCode != null) {
      setState(() {
        _locale = Locale(languageCode, '');
      });
    }
  }

//_saveLocaleToPreferences 方法用于将选择的语言环境保存到 SharedPreferences 中,以便下次启动应用时可以加载该语言环境。
  Future<void> _saveLocaleToPreferences(Locale locale) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setString('languageCode', locale.languageCode);
  }

  void setLocale(Locale newLocale) {
    _saveLocaleToPreferences(newLocale);
    setState(() {
      _locale = newLocale;
    });
  }

  @override
  void initState() {
    super.initState();
    _loadLocaleFromPreferences();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const LoginPage(),
      localizationsDelegates: const [
        AppLocalizationsDelegate(),
        ...GlobalMaterialLocalizations.delegates,
        GlobalWidgetsLocalizations.delegate,
      ],
      //localizationsDelegates 参数包含了用于本地化的委托,包括我们自定义的 AppLocalizationsDelegate 和 Flutter 提供的 GlobalMaterialLocalizations 和 GlobalWidgetsLocalizations。
      //supportedLocales 参数定义了支持的语言环境,包括英文和中文。最后,我们将 _locale 赋给 locale 参数,设置当前的语言环境。
      supportedLocales: const [
        Locale('en', ''),
        Locale('zh', ''),
      ],
      locale: _locale, // 设置当前语言
    );
  }
}

第三步:登录页LoginPage.dart

import 'package:flutter/material.dart';

import '../l10n/messages.dart';
import '../main.dart';

class LoginPage extends StatefulWidget {
  const LoginPage({super.key});

  @override
  State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  final TextEditingController _usernameController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  @override
  void dispose() {
    _usernameController.dispose();
    _passwordController.dispose();
    super.dispose();
  }
//_toggleLanguage 方法用于切换应用程序的语言环境。它通过获取当前的语言环境,然后根据当前语言代码切换到相应的新语言环境(英文切换为中文,中文切换为英文)
  void _toggleLanguage(BuildContext context) {
    var currentLocale = Localizations.localeOf(context);
    var newLocale = currentLocale.languageCode == 'en'
        ? const Locale('zh', '')
        : const Locale('en', '');

    MyApp.setLocale(context, newLocale);
  }

  @override
  Widget build(BuildContext context) {
    var messages = AppLocalizations.of(context)!;
    return Scaffold(
      backgroundColor: const Color.fromRGBO(205, 205, 205, 1),
      body: SizedBox(
        height: double.infinity,
        child: Column(
          children: [
            const HeadImageWidget(),
            Expanded(
                flex: 1,
                child: Container(
                  width: double.infinity,
                  decoration: const BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.only(
                          topLeft: Radius.circular(20),
                          topRight: Radius.circular(20))),
                  padding: const EdgeInsets.all(30),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        messages['loginTitle1'],
                        style: const TextStyle(
                            color: Color.fromRGBO(83, 88, 110, 1),
                            fontSize: 26),
                      ),
                      Text(
                        messages['loginTitle2'],
                        style: const TextStyle(
                            color: Color.fromRGBO(205, 205, 205, 1),
                            fontSize: 16),
                      ),
                      const SizedBox(height: 30),
                      TextField(
                        controller: _usernameController,
                        decoration: InputDecoration(
                          labelText: messages['username'],
                        ),
                      ),
                      const SizedBox(height: 16),
                      TextField(
                        controller: _passwordController,
                        obscureText: true,
                        decoration: InputDecoration(
                          labelText: messages['password'],
                        ),
                      ),
                      const SizedBox(height: 30),
                      Container(
                        height: 48,
                        width: double.infinity,
                        decoration: BoxDecoration(
                          color: const Color.fromRGBO(64, 74, 124, 1),
                          borderRadius: BorderRadius.circular(8),
                        ),
                        child: ElevatedButton(
                          onPressed: () {},
                          style: ElevatedButton.styleFrom(
                            backgroundColor: Colors.transparent,
                            elevation: 0,
                            shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(8)),
                          ),
                          child: Text(
                            messages['login'],
                          ),
                        ),
                      ),
                      const Spacer(),
                      Center(
                        child: GestureDetector(
                          onTap: () => _toggleLanguage(context),
                          child: Text(
                            messages['language'],
                          ),
                        ),
                      )
                    ],
                  ),
                ))
          ],
        ),
      ),
    );
  }
}

class HeadImageWidget extends StatelessWidget {
  const HeadImageWidget({super.key});
  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: 200,
      padding: const EdgeInsets.only(top: 50),
      color: const Color.fromRGBO(205, 205, 205, 1),
      child: Image.asset('assets/login/fooderise_image.png'),
    );
  }
}

快去试试8!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值