Flutter国家输入插件input_country的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter国家输入插件input_country的使用

简介

input_country 是一个Flutter插件,提供了关于国家、货币和语言的数据,并为每个数据类型提供了一个选择小部件(下拉框)。所有小部件都继承自 FormField,因此可以独立使用或嵌入到 Form 中。每个可选项目和选择结果都可以显示国旗。

主要功能

  • 国家:提供ISO-3166标准的国家代码、国际电话区号、官方语言和货币等信息。
  • 货币:提供ISO-4217标准的货币代码、小数位数和货币符号。
  • 语言:提供ISO-639标准的语言代码和主要使用该语言的国家。

完整示例Demo

以下是一个完整的示例代码,展示了如何在Flutter应用中使用 input_country 插件来选择国家、货币和语言。

import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:input_country/input_country.dart';

const double SAFE_AREA_PADDING = 5.0;

/// Entry point for example application
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  MyApp() {
    LocaleHandler.initialize(window.locale);
  }

  // This widget is the root of your application.
  [@override](/user/override)
  Widget build(BuildContext context) {
    return ValueListenableBuilder<Locale>(
        valueListenable: LocaleHandler.thisAppsLocaleNotifier,
        builder: (BuildContext ctx, Locale locale, Widget? child) {
          debugPrint('--- builder called --- locale=$locale');
          return MaterialApp(
            home: MyHomePage(),
            locale: locale,
            localizationsDelegates: [
              GlobalMaterialLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate,
              GlobalCupertinoLocalizations.delegate,
            ],
            supportedLocales: LocaleHandler.supportedLocales,
            theme: ThemeData(
              primarySwatch: Colors.orange,
            ),
            title: 'input_country',
          );
        });
  }
}

class MyHomePage extends StatefulWidget {
  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String? _countryCode1, _currencyCode1, _countryCode2, _currencyCode2;
  Locale? _language1;
  Locale _language2 = window.locale;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('input_country 示例'),
      ),
      body: SafeArea(
        minimum: EdgeInsets.all(SAFE_AREA_PADDING),
        child: SingleChildScrollView(
          child: _buildBody(context),
        ),
      ),
    );
  }

  Widget _buildBody(BuildContext context) {
    return Center(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          _buildLanguageSelection(context),
          _buildAllItems(context),
          _buildSelectableItems(context),
        ],
      ),
    );
  }

  Widget _buildLanguageSelection(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(SAFE_AREA_PADDING),
      child: InputDecorator(
        decoration: InputDecoration(
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(8.0),
          ),
          labelText: '应用程序语言选择',
        ),
        child: Table(
            columnWidths: {
              0: FlexColumnWidth(2.0),
              1: FlexColumnWidth(7.0),
            },
            defaultVerticalAlignment: TableCellVerticalAlignment.middle,
            children: [
              TableRow(children: [
                Text('window.locale'),
                Text('= ${window.locale}'),
              ]),
              TableRow(children: [
                Text('useLocaleFromPlatform'),
                Text('= ${LocaleHandler.isLocaleFromPlatform}'),
              ]),
              TableRow(children: [
                Text('thisAppsLocale'),
                Text('= ${LocaleHandler.thisAppsLocale}'),
              ]),
              TableRow(children: [
                Text('Localization.code'),
                Text('= ${Localization.langCode}'),
              ]),
              TableRow(children: [
                Text('选择语言'),
                InputLanguage(
                  initialValue: LocaleHandler.thisAppsLocale,
                  onChanged: (Locale? newLang) =>
                      LocaleHandler.thisAppsLocale = newLang,
                  selectableLocales: LocaleHandler.supportedLocales,
                  withPlatformSelection: true,
                ),
              ]),
            ]),
      ),
    );
  }

  Widget _buildAllItems(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(SAFE_AREA_PADDING),
      child: InputDecorator(
        decoration: InputDecoration(
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(8.0),
          ),
          labelText: '所有项目',
        ),
        child: Table(
          columnWidths: {
            0: FlexColumnWidth(2.0),
            1: FlexColumnWidth(7.0),
            2: FlexColumnWidth(1.0),
          },
          defaultVerticalAlignment: TableCellVerticalAlignment.middle,
          children: [
            TableRow(
              children: [
                Text('所有'),
                Text('选择'),
                Text('代码'),
              ],
            ),
            TableRow(
              children: [
                Text('国家'),
                InputCountry(
                  showFlagOnSelection: true,
                  showFlagOnItems: true,
                  initialValue: _countryCode1,
                  onChanged: (String? newCode) =>
                      setState(() => _countryCode1 = newCode),
                ),
                Text('$_countryCode1'),
              ],
            ),
            TableRow(
              children: [
                Text('货币'),
                InputCurrency(
                  initialValue: _currencyCode1,
                  onChanged: (String? newCode) =>
                      setState(() => _currencyCode1 = newCode),
                ),
                Text('$_currencyCode1'),
              ],
            ),
            TableRow(children: [
              Text('语言'),
              InputLanguage(
                initialValue: _language1,
                onChanged: (Locale? newLang) =>
                    setState(() => _language1 = newLang),
                showFlagOnItems: true,
                showFlagOnSelection: true,
                withPlatformSelection: true,
              ),
              Text('$_language1'),
            ]),
          ],
        ),
      ),
    );
  }

  Widget _buildSelectableItems(BuildContext context) {
    List<String> _selectableCountries = ['DE', 'ES', 'FR', 'IT'];
    List<String> _selectableCurrencies = ['EUR', 'USD'];
    List<Locale> _selectableLocales = [Locale('en'), Locale('es')];

    return Padding(
      padding: EdgeInsets.all(SAFE_AREA_PADDING),
      child: InputDecorator(
        decoration: InputDecoration(
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(8.0),
          ),
          labelText: '可选项目',
        ),
        child: Table(
          columnWidths: {
            0: FlexColumnWidth(2.0),
            1: FlexColumnWidth(7.0),
            2: FlexColumnWidth(1.0),
          },
          defaultVerticalAlignment: TableCellVerticalAlignment.middle,
          children: [
            TableRow(
              children: [
                Text('可选'),
                Text('选择'),
                Text('代码'),
              ],
            ),
            TableRow(
              children: [
                Text('$_selectableCountries'),
                InputCountry(
                  initialValue: _countryCode2,
                  onChanged: (String? newCode) =>
                      setState(() => _countryCode2 = newCode),
                  selectableCountries: _selectableCountries,
                ),
                Text('$_countryCode2'),
              ],
            ),
            TableRow(
              children: [
                Text('$_selectableCurrencies'),
                InputCurrency(
                  initialValue: _currencyCode2,
                  onChanged: (String? newCode) =>
                      setState(() => _currencyCode2 = newCode),
                  selectableCurrencies: _selectableCurrencies,
                ),
                Text('$_currencyCode2'),
              ],
            ),
            TableRow(children: [
              Text('语言'),
              InputLanguage(
                initialValue: _language2,
                onChanged: (Locale? newLang) =>
                    setState(() => _language2 = newLang!),
                selectableLocales: _selectableLocales,
              ),
              Text('${_language2.languageCode}'),
            ]),
          ],
        ),
      ),
    );
  }
}

///
/// 结合功能以处理应用程序的区域设置更改。
///
/// 初始设置:
/// * `thisAppsLocale.value = window.locale`
/// * `useLocaleFromPlatform` = true
///
class LocaleHandler {
  /// 如果没有其他匹配项,则使用的默认区域设置
  static const DEFAULT_LOCALE = Locale('en', 'US');

  /// 支持的区域设置。第一个条目 `en` 是默认值。
  static const List<Locale> supportedLocales = [
    DEFAULT_LOCALE,
    Locale('de', 'DE'),
    Locale('es', 'ES'),
  ];

  /// 由 initialize 设置
  static late ValueNotifier<Locale> thisAppsLocaleNotifier;

  /// 由 initialize 设置
  static late Locale _thisAppsLocale;

  static Locale get thisAppsLocale => _thisAppsLocale;

  /// 设置要使用的区域设置。
  /// 返回实际使用的解析后的区域设置。
  static set thisAppsLocale(Locale? newLocale) {
    Locale localeToSet;
    if ((newLocale == null) ||
        (newLocale.languageCode == Language.LANG_CODE_FROM_PLATFORM)) {
      localeToSet = window.locale;
      _isLocaleFromPlatform = true;
    } else {
      localeToSet = newLocale;
      _isLocaleFromPlatform = false;
    }
    Locale resolvedLocale = _resolveLocaleToUse(localeToSet);
    _thisAppsLocale = resolvedLocale;
    thisAppsLocaleNotifier.value = resolvedLocale;
    Localization.langCode = resolvedLocale.languageCode;
    debugPrint(
        'set thisAppsLocale( $newLocale ) // fromPlatform=$_isLocaleFromPlatform -> use=$resolvedLocale');
  }

  static bool _isLocaleFromPlatform = false;
  static bool get isLocaleFromPlatform => _isLocaleFromPlatform;

  static bool _breakCircularCallFromMaterialApp = true;

  static void initialize(Locale startupLocale) {
    _thisAppsLocale = _resolveLocaleToUse(window.locale);
    thisAppsLocaleNotifier = ValueNotifier<Locale>(_thisAppsLocale);
    Localization.langCode = _thisAppsLocale.languageCode;
  }

  /// 回调方法用于 [MaterialApp]
  static Locale localeResolutionCallback(
      Locale? newLocale, Iterable<Locale> appLocales) {
    thisAppsLocale = newLocale;
    debugPrint(
        'localeResolutionMethod( $newLocale, $appLocales ) -> $thisAppsLocale');
    return thisAppsLocale;
  }

  static Locale _resolveLocaleToUse(Locale? newLocale) {
    if (newLocale != null) {
      String langCode = newLocale.languageCode;
      for (Locale loc in supportedLocales) {
        if (langCode == loc.languageCode) {
          return loc;
        }
      }
    }
    return DEFAULT_LOCALE;
  }
}

更多关于Flutter国家输入插件input_country的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter国家输入插件input_country的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用input_country插件的一个示例代码案例。input_country插件可以帮助用户选择一个国家,并获取相关的国家信息。

首先,确保你已经在pubspec.yaml文件中添加了input_country依赖:

dependencies:
  flutter:
    sdk: flutter
  input_country: ^最新版本号  # 请替换为实际最新版本号

然后,运行flutter pub get来安装依赖。

接下来,你可以在你的Flutter项目中使用input_country插件。以下是一个完整的示例代码,展示了如何使用这个插件来选择国家并显示所选国家的详细信息:

import 'package:flutter/material.dart';
import 'package:input_country/input_country.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Country? selectedCountry;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Select a Country'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () async {
                final result = await showCountryPicker(
                  context: context,
                  favorite: ['US', 'CN', 'IN'], // 可选的,预选的国家代码列表
                  searchHint: 'Search for a country...',
                  selectionColor: Colors.blue,
                );
                if (result != null) {
                  setState(() {
                    selectedCountry = result;
                  });
                }
              },
              child: Text('Select Country'),
            ),
            SizedBox(height: 20),
            if (selectedCountry != null)
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Text('Country Code: ${selectedCountry!.dialCode}'),
                  Text('Country Name: ${selectedCountry!.name}'),
                  Text('Country Flag: ${selectedCountry!.emoji}'),
                ],
              ),
          ],
        ),
      ),
    );
  }
}

在这个示例中:

  1. 我们定义了一个MyApp类作为应用的根组件。
  2. MyHomePage是一个有状态的组件,它包含一个按钮和一个显示所选国家信息的区域。
  3. 当用户点击按钮时,会调用showCountryPicker函数来显示国家选择器对话框。
  4. 用户选择一个国家后,showCountryPicker会返回一个Country对象,我们将该对象保存在selectedCountry变量中。
  5. 如果selectedCountry不为空,则显示所选国家的代码、名称和国旗emoji。

请确保你已经正确导入了input_country包,并根据需要调整代码中的细节。这个示例展示了如何使用input_country插件来选择和显示国家信息。

回到顶部