Flutter国家选择器插件custom_country_picker的使用

Flutter国家选择器插件custom_country_picker的使用

简介

Custom Country Picker 是一个Flutter插件,提供了一个易于使用且高度可定制的国家选择器小部件。该插件适用于需要用户选择国家的应用程序,例如设置位置、配置电话号码或其他与国家相关的选择。

安装

pubspec.yaml 文件中添加以下依赖项:

dependencies:
  custom_country_picker: ^1.0.2

然后在需要使用的文件中导入 custom_country_picker

import 'package:custom_country_picker/custom_country_picker.dart';

需求

此插件使用SVG格式的国家旗帜图像。如果你需要自定义显示包含图像的选择器,你需要安装 Flutter SVG

dependencies:
  flutter_svg: ^2.0.10+1

如果你需要在输入框中自定义国家旗帜,可以使用以下代码:

SvgPicture.asset(
  country.flag,
  width: MediaQuery.of(context).size.width * 0.08,
  package: 'custom_country_picker'
)

使用方法

使用 Custom Country Picker 插件时,需要提供一些参数来确保其正常工作。以下是主要参数及其说明:

参数 类型 说明
language String? 定义使用的语言,默认值为 fr(法语)
initial String? 初始选择的国家,默认值为 CI(科特迪瓦)
theme CountryTheme? 国家主题
appBar PreferredSizeWidget? 自定义AppBar
useUiOverlay bool 是否允许小部件设置自定义UI覆盖层
useSafeArea bool 是否将国家列表包裹在SafeArea中
usePicker bool 是否启用选择器(启用或禁用选择器)
countries List<String> 自定义国家列表,默认使用所有国家
onChanged ValueChanged<Country?>? 选择变化时的回调函数
builder Function(BuildContext context, Country? country)? 自定义显示已选择的国家

示例代码

以下是一个完整的示例代码,展示了如何使用 Custom Country Picker 插件:

import 'package:custom_country_picker/country.dart';
import 'package:flutter/material.dart';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom Country Picker Example',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Custom Country Picker Example'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController phoneController = TextEditingController();
  TextEditingController phone1Controller = TextEditingController();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Padding(
          padding: EdgeInsets.symmetric(horizontal: MediaQuery.of(context).size.width * 0.05),
          child: SingleChildScrollView(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                // 所有国家带选择器
                Text('所有国家带选择器', style: TextStyle(fontSize: MediaQuery.of(context).size.width * 0.045, fontWeight: FontWeight.bold)),
                SizedBox(height: MediaQuery.of(context).size.height * 0.005),
                Padding(
                  padding: EdgeInsets.symmetric(horizontal: MediaQuery.of(context).size.width * 0.15),
                  child: Stack(
                    alignment: Alignment.topLeft,
                    children: [
                      Container(
                        margin: EdgeInsets.only(top: MediaQuery.of(context).size.width * 0.035),
                        decoration: BoxDecoration(border: Border.all(color: Colors.deepPurple), borderRadius: BorderRadius.circular(10)),
                        child: CountrySelect(
                          onChanged: (Country? country) {},
                          language: 'en',
                          initial: 'CI',
                        ),
                      ),
                      Positioned(
                        left: MediaQuery.of(context).size.width * 0.03,
                        child: Container(
                          padding: EdgeInsets.symmetric(horizontal: MediaQuery.of(context).size.width * 0.01, vertical: MediaQuery.of(context).size.width * 0.002),
                          color: Colors.white,
                          child: Text('国家', style: TextStyle(fontSize: MediaQuery.of(context).size.width * 0.035)),
                        ),
                      ),
                    ],
                  ),
                ),
                SizedBox(height: MediaQuery.of(context).size.height * 0.05),

                // 所有国家不带选择器
                Text('所有国家不带选择器', style: TextStyle(fontSize: MediaQuery.of(context).size.width * 0.045, fontWeight: FontWeight.bold)),
                SizedBox(height: MediaQuery.of(context).size.height * 0.005),
                Padding(
                  padding: EdgeInsets.symmetric(horizontal: MediaQuery.of(context).size.width * 0.15),
                  child: Stack(
                    alignment: Alignment.topLeft,
                    children: [
                      Container(
                        margin: EdgeInsets.only(top: MediaQuery.of(context).size.width * 0.035),
                        decoration: BoxDecoration(border: Border.all(color: Colors.deepPurple), borderRadius: BorderRadius.circular(10)),
                        child: CountrySelect(
                          onChanged: (Country? country) {},
                          language: 'fr',
                          usePicker: false,
                          initial: 'CI',
                        ),
                      ),
                      Positioned(
                        left: MediaQuery.of(context).size.width * 0.03,
                        child: Container(
                          padding: EdgeInsets.symmetric(horizontal: MediaQuery.of(context).size.width * 0.01, vertical: MediaQuery.of(context).size.width * 0.002),
                          color: Colors.white,
                          child: Text('国家', style: TextStyle(fontSize: MediaQuery.of(context).size.width * 0.035)),
                        ),
                      ),
                    ],
                  ),
                ),
                SizedBox(height: MediaQuery.of(context).size.height * 0.05),

                // 包含所有国家的列表
                Text('包含所有国家的列表', style: TextStyle(fontSize: MediaQuery.of(context).size.width * 0.045, fontWeight: FontWeight.bold)),
                SizedBox(height: MediaQuery.of(context).size.height * 0.005),
                PhoneInputWidget(controller: phoneController, label: '电话号码'),
                SizedBox(height: MediaQuery.of(context).size.height * 0.05),

                // 包含部分国家的列表
                Text('包含部分国家的列表', style: TextStyle(fontSize: MediaQuery.of(context).size.width * 0.045, fontWeight: FontWeight.bold)),
                SizedBox(height: MediaQuery.of(context).size.height * 0.005),
                PhoneInputWidget(
                  countries: const ['CI', 'CM', 'SN', 'ML', 'BF'],
                  controller: phone1Controller,
                  label: '电话号码',
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

// 自定义的电话输入组件
class PhoneInputWidget extends StatelessWidget {
  final TextEditingController controller;
  final String label;
  final List<String>? countries;

  const PhoneInputWidget({
    Key? key,
    required this.controller,
    required this.label,
    this.countries,
  }) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(label, style: TextStyle(fontSize: MediaQuery.of(context).size.width * 0.035)),
        SizedBox(height: MediaQuery.of(context).size.height * 0.01),
        Container(
          decoration: BoxDecoration(border: Border.all(color: Colors.deepPurple), borderRadius: BorderRadius.circular(10)),
          child: Row(
            children: [
              Expanded(
                child: TextField(
                  controller: controller,
                  decoration: InputDecoration(
                    border: InputBorder.none,
                    contentPadding: EdgeInsets.symmetric(horizontal: MediaQuery.of(context).size.width * 0.03),
                  ),
                ),
              ),
              if (countries != null)
                CountrySelect(
                  onChanged: (Country? country) {},
                  language: 'en',
                  countries: countries!,
                  initial: 'CI',
                ),
            ],
          ),
        ),
      ],
    );
  }
}

更多关于Flutter国家选择器插件custom_country_picker的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

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


当然,以下是如何在Flutter项目中使用custom_country_picker插件的一个简单示例。这个插件允许你选择一个国家,并获取其相关信息,如国家代码、拨号代码等。

首先,你需要在pubspec.yaml文件中添加custom_country_picker依赖:

dependencies:
  flutter:
    sdk: flutter
  custom_country_picker: ^2.0.0  # 请检查最新版本号

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

接下来,你可以在你的Flutter应用中使用这个插件。以下是一个完整的示例代码,展示如何集成和使用custom_country_picker

import 'package:flutter/material.dart';
import 'package:custom_country_picker/custom_country_picker.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('Country Picker Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              selectedCountry == null
                  ? 'Please select a country'
                  : '${selectedCountry!.name} (+${selectedCountry!.phoneCode})',
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                final result = await showDialog(
                  context: context,
                  builder: (BuildContext context) {
                    return AlertDialog(
                      title: Text('Select a Country'),
                      content: SizedBox(
                        height: 400, // Adjust the height as needed
                        child: CountryPicker(
                          onChanged: (Country country) {
                            setState(() {
                              selectedCountry = country;
                            });
                          },
                          favorite: [
                            'us', // Example of favorite countries
                            'cn',
                          ],
                          searchCursorColor: Colors.blue,
                          searchInactiveIcon: Icon(Icons.search_outlined),
                          searchActiveIcon: Icon(Icons.clear),
                          selectionColor: Colors.blue,
                          initialSelection: 'us', // Initial selected country code
                        ),
                      ),
                      actions: <Widget>[
                        TextButton(
                          onPressed: () {
                            Navigator.of(context).pop();
                          },
                          child: Text('Cancel'),
                        ),
                        TextButton(
                          onPressed: () {
                            if (selectedCountry != null) {
                              Navigator.of(context).pop();
                            }
                          },
                          child: Text('OK'),
                        ),
                      ],
                    );
                  },
                );
              },
              child: Text('Select Country'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中:

  1. CountryPicker被嵌入到一个AlertDialog中,当用户点击按钮时显示对话框。
  2. 用户可以在对话框中选择一个国家。
  3. 选择完成后,onChanged回调会更新selectedCountry状态,并在UI中显示所选国家的名称和电话代码。
  4. favorite属性允许你指定一些默认的国家作为“收藏”或“常用”国家。
  5. initialSelection属性允许你设置初始选中的国家代码。

你可以根据需求调整这个示例,例如修改对话框的布局、添加更多的国家到收藏列表、或者处理用户取消选择的情况。

回到顶部