Flutter电话号码输入插件phone_input的使用

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

Flutter电话号码输入插件phone_input的使用

phone_input 是一个多功能的包,它为电话号码输入字段提供了跨平台支持。这个包旨在简化从用户那里获取电话号码的过程。以下是 phone_input 插件的主要功能和使用方法。

功能特性

  • 跨平台兼容性:支持多种平台。
  • 自动电话号码格式化:根据选择的国家自动格式化电话号码。
  • 实时电话号码验证:在用户输入时进行实时验证。
  • 多种选择国家的方法:提供灵活的自定义选项来选择国家。
  • 与自定义文本字段集成:可以与任何自定义或标准文本字段一起使用。
  • 地区本地化:支持不同地区的本地化显示。

示例代码

以下是一个完整的示例代码,展示了如何在Flutter应用中使用 phone_input 插件:

import 'package:flutter/material.dart';
import 'package:phone_input/phone_input_package.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const PhoneInputPage(),
    );
  }
}

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

  @override
  State<PhoneInputPage> createState() => _PhoneInputPageState();
}

enum FieldType { outlined, underlined }

class _PhoneInputPageState extends State<PhoneInputPage> {
  FieldType fieldType = FieldType.outlined;
  LayerLink layerLink = LayerLink();
  bool _shouldFormat = true;
  bool _isFlagCircle = true;
  bool _showFlagInInput = true;
  bool _showArrow = true;
  late List<CountrySelectorNavigator> navigators;
  late CountrySelectorNavigator selectorNavigator;
  List<String> nameOfNavigators = [
    'Page',
    'Dialog',
    'Bottom Sheet',
    'Modal Bottom Sheet',
    'Draggable Bottom Sheet',
    'Dropdown',
  ];

  @override
  void initState() {
    super.initState();
    navigators = <CountrySelectorNavigator>[
      const CountrySelectorNavigator.searchDelegate(),
      const CountrySelectorNavigator.dialog(),
      const CountrySelectorNavigator.bottomSheet(),
      const CountrySelectorNavigator.modalBottomSheet(),
      const CountrySelectorNavigator.draggableBottomSheet(),
      CountrySelectorNavigator.dropdown(
        backgroundColor: const Color(0xFFE7DEF6),
        borderRadius: BorderRadius.circular(5),
        layerLink: layerLink,
        showSearchInput: true,
      ),
    ];
    selectorNavigator = navigators.first;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Phone input demo')),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              const SizedBox(height: 12),
              ConstrainedBox(
                constraints: const BoxConstraints(minWidth: double.infinity),
                child: SegmentedButton<FieldType>(
                  onSelectionChanged: (value) {
                    setState(() {
                      fieldType = value.first;
                    });
                  },
                  segments: const [
                    ButtonSegment<FieldType>(
                      value: FieldType.outlined,
                      label: Text("Outlined"),
                    ),
                    ButtonSegment<FieldType>(
                      value: FieldType.underlined,
                      label: Text("Underlined"),
                    ),
                  ],
                  selected: <FieldType>{fieldType},
                ),
              ),
              const SizedBox(height: 24),
              PhoneInput(
                showArrow: _showArrow,
                shouldFormat: _shouldFormat,
                validator:
                    PhoneValidator.compose([PhoneValidator.required(), PhoneValidator.valid()]),
                flagShape: _isFlagCircle ? BoxShape.circle : BoxShape.rectangle,
                showFlagInInput: _showFlagInInput,
                decoration: InputDecoration(
                  labelText: 'Phone number',
                  border: switch (fieldType) {
                    FieldType.outlined => const OutlineInputBorder(),
                    FieldType.underlined => const UnderlineInputBorder(),
                  },
                ),
                countrySelectorNavigator: selectorNavigator,
              ),
              const SizedBox(height: 8),
              SwitchListTile(
                title: const Text('Should format'),
                value: _shouldFormat,
                onChanged: (bool value) {
                  setState(() {
                    _shouldFormat = value;
                  });
                },
              ),
              SwitchListTile(
                title: const Text('Circle flag'),
                value: _isFlagCircle,
                onChanged: (bool value) {
                  setState(() {
                    _isFlagCircle = value;
                  });
                },
              ),
              SwitchListTile(
                title: const Text('Show flag in input'),
                value: _showFlagInInput,
                onChanged: (bool value) {
                  setState(() {
                    _showFlagInInput = value;
                  });
                },
              ),
              SwitchListTile(
                title: const Text('Show arrow'),
                value: _showArrow,
                onChanged: (bool value) {
                  setState(() {
                    _showArrow = value;
                  });
                },
              ),
              ListTile(
                title: Wrap(
                  alignment: WrapAlignment.spaceBetween,
                  crossAxisAlignment: WrapCrossAlignment.center,
                  children: [
                    const Text('Country Selector'),
                    DropdownButton<CountrySelectorNavigator>(
                      value: selectorNavigator,
                      onChanged: (CountrySelectorNavigator? value) {
                        if (value != null) {
                          setState(() => selectorNavigator = value);
                        }
                      },
                      items: navigators
                          .asMap()
                          .entries
                          .map<DropdownMenuItem<CountrySelectorNavigator>>(
                        (entry) {
                          int index = entry.key;
                          CountrySelectorNavigator value = entry.value;
                          return DropdownMenuItem<CountrySelectorNavigator>(
                            value: value,
                            child: Text(nameOfNavigators[index]),
                          );
                        },
                      ).toList(),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

国家选择器

你可以选择不同的选择器来选择国家,例如对话框、底部表单等。每个选择器都有其特定的参数,可以根据需要进行定制。

内置国家选择器

名称 描述
Search Delegate 打开页面以选择国家
Dialog 打开对话框以选择国家
Bottom Sheet 打开底部表单以选择国家
Modal Bottom Sheet 打开模态底部表单
Draggable Bottom Sheet 打开可拖动的模态底部表单
Dropdown 在文本输入下方打开下拉菜单

验证

Phone Input 提供了多种内置验证器,如 requiredvalidvalid country 等。你还可以通过 PhoneValidator.compose() 方法组合多个验证器。

国际化

你可以通过 MaterialApplocalizationsDelegatessupportedLocales 参数来集成国际化支持。phone_input 插件内置支持多种语言,包括但不限于阿拉伯语、德语、英语、希腊语、西班牙语、法语、印地语、意大利语、荷兰语、葡萄牙语、俄语、乌克兰语、土耳其语、中文、瑞典语。

return MaterialApp(
  localizationsDelegates: [
    GlobalMaterialLocalizations.delegate,
    PhoneFieldLocalization.delegate
  ],
  supportedLocales: [
    const Locale('en', ''),
    const Locale('es', ''),
    const Locale('fr', ''),
    const Locale('uk', ''),
    // Add more locales as needed
  ],
);

通过上述内容,你应该能够顺利地在Flutter项目中使用 phone_input 插件来处理电话号码输入。


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

1 回复

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


当然,下面是一个关于如何在Flutter应用中使用phone_input插件来实现电话号码输入的示例代码。这个插件可以方便地帮助用户输入和验证电话号码。

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

dependencies:
  flutter:
    sdk: flutter
  phone_input: ^x.y.z  # 请将x.y.z替换为当前最新版本号

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

接下来,在你的Flutter项目中,可以按照以下步骤使用phone_input插件:

  1. 导入必要的包
import 'package:flutter/material.dart';
import 'package:phone_input/phone_input.dart';
  1. 创建一个包含电话号码输入的页面
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: PhoneInputScreen(),
    );
  }
}

class PhoneInputScreen extends StatefulWidget {
  @override
  _PhoneInputScreenState createState() => _PhoneInputScreenState();
}

class _PhoneInputScreenState extends State<PhoneInputScreen> {
  final _formKey = GlobalKey<FormState>();
  String? _phoneNumber;
  PhoneInputValidationResult? _validationResult;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Phone Input Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              PhoneInput(
                initialCountry: 'us',  // 初始国家代码,可以根据需要设置
                favorite: ['+1', 'us'], // 收藏的国家代码,这些会优先显示在列表中
                countries: ['us', 'cn', 'in', 'br'], // 可以限制只显示这些国家
                enableFiltering: true,
                enableAreaCode: true,
                autoFormat: true,
                onError: (result) {
                  setState(() {
                    _validationResult = result;
                  });
                },
                onChanged: (phone) {
                  setState(() {
                    _phoneNumber = phone.completeNumber;
                  });
                },
                selectorConfig: SelectorConfig(
                  backgroundColor: Colors.white,
                ),
                textFieldConfig: TextFieldConfig(
                  decoration: InputDecoration(
                    labelText: 'Phone Number',
                    errorText: _validationResult?.error,
                  ),
                ),
              ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: () {
                  if (_formKey.currentState?.validate() ?? false) {
                    // 处理验证通过的逻辑
                    print('Phone Number: $_phoneNumber');
                  }
                },
                child: Text('Submit'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

在这个示例中,我们使用了PhoneInput组件来输入电话号码,并配置了一些基本的参数,如初始国家代码、收藏的国家代码、限制显示的国家列表等。我们还设置了onErroronChanged回调函数来处理输入过程中的错误和变化。

请注意,这里的Form组件和_formKey主要用于示例中的表单验证。在实际应用中,你可能需要根据具体需求进行更多的配置和错误处理。

这个示例展示了如何使用phone_input插件来创建一个电话号码输入字段,并处理用户输入和验证。你可以根据需要进行进一步的定制和扩展。

回到顶部