flutter_simple_country_picker 0.8.0 copy "flutter_simple_country_picker: ^0.8.0" to clipboard
flutter_simple_country_picker: ^0.8.0 copied to clipboard

An easy-to-use country selection widget for Flutter. Allows users to select a country from a comprehensive list. Supports Android, iOS, web, Windows and Linux platforms.

flutter_simple_country_picker #

Dart SDK Version Pub Version Actions Status codecov License: MIT Style: flutter lints

Description #

An easy-to-use country selection widget for Flutter. Allows users to select a country from a comprehensive list. Supports Android, iOS, macOS, Web, Windows and Linux platforms. Includes a phone-number input widget with automatic mask formatting, adaptive bottom sheet, theme customization, and 35+ locales.

Quick Start #

Add the package and register the localization delegate, then open the picker:

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_simple_country_picker/flutter_simple_country_picker.dart';

MaterialApp(
  localizationsDelegates: [
    CountryLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalMaterialLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
  ],
  // Pass the built-in list directly — no need to enumerate locales manually.
  supportedLocales: CountryLocalizations.supportedLocales,
  home: const MyHomePage(),
);

// Inside your widget:
showCountryPicker(
  context: context,
  onSelect: (Country country) {
    print(country.displayName); // e.g. “Russia (+7)”
  },
);

Getting Started #

Add the package to your pubspec.yaml:

flutter_simple_country_picker: ^latest

Import the library in your Dart file:

import 'package:flutter_simple_country_picker/flutter_simple_country_picker.dart';

Setup Localizations #

Add CountryLocalizations.delegate to your app's localizationsDelegates and list the locales you want to support.

MaterialApp(
  locale: const Locale('en'),
  supportedLocales: const <Locale>[
    Locale('en'),
    Locale('ru'),
  ],
  localizationsDelegates: [
    CountryLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalMaterialLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
  ],
  home: const HomePage(),
);

Tip: pass CountryLocalizations.supportedLocales to supportedLocales to enable all 36 built-in locales at once.

Supported locales: ar, bg, ca, cs, da, de, el, en, es, et, fa, fr, he, hi, hr, ht, id, it, ja, ko, ku, lt, lv, nb, ne, nl, nn, pl, pt, ro, ru, sk, tr, uk, zh-Hans (Simplified Chinese), zh-Hant (Traditional Chinese).

Custom localizations #

CountryLocalizations is an abstract class. You can extend it to add a new language or override existing strings without forking the package:

final class CountryLocalizationsMyLang extends CountryLocalizations {
  const CountryLocalizationsMyLang();

  @override
  String get cancelButton => 'Cancel';

  @override
  String get phonePlaceholder => 'Phone number';

  @override
  String get searchPlaceholder => 'Search country';

  @override
  String get selectCountryLabel => 'Select country';

  @override
  String? countryName(String countryCode) => _names[countryCode];
}

const Map<String, String> _names = {
  'US': 'United States',
  'RU': 'Russia',
  // …
};

Register it in the delegate by creating your own LocalizationsDelegate<CountryLocalizations> that returns your subclass for the desired locale, or contribute it back to the package.

Usage #

showCountryPicker #

Opens a bottom sheet with a scrollable/searchable country list.

showCountryPicker(
  context: context,
  exclude: const ['RU'],
  favorites: const ['US', 'GB'],
  onSelect: (Country country) {
    debugPrint('Selected: ${country.displayName}');
  },
  whenComplete: () {
    debugPrint('Picker dismissed');
  },
);

Parameters

Parameter Type Default Description
context BuildContext Required. Build context.
onSelect SelectCountryCallback? null Called when a country is selected.
whenComplete VoidCallback? null Called when the picker is dismissed, regardless of selection.
exclude List<String>? null ISO2 codes of countries to exclude.
favorites List<String>? null ISO2 codes of countries to pin at the top.
filter List<String>? null ISO2 codes to show exclusively. Cannot be combined with exclude.
selected SelectedCountry? null Notifier holding the pre-selected country.
expand bool false Expand the bottom sheet to full height.
adaptive bool false Uses a Cupertino-style modal on iOS.
autofocus bool false Automatically focuses the search field.
isDismissible bool true Whether the sheet can be dismissed by tapping the barrier.
isScrollControlled bool true Controls scroll behavior of the modal.
shouldCloseOnSwipeDown bool false Closes the sheet on swipe-down gesture.
showPhoneCode bool false Displays the country phone code in the list.
showWorldWide bool false Shows a "World Wide" entry at the top.
showGroup bool? null Groups countries by their first letter.
showSearch bool? null Shows or hides the search bar.
useHaptickFeedback bool true Enables haptic feedback on selection.
useRootNavigator bool true Uses the root navigator to display the sheet above all other routes.
useSafeArea bool true Wraps the sheet in a SafeArea.
initialChildSize double? null Initial fractional height of the draggable sheet.
minChildSize double? null Minimum fractional height of the draggable sheet.

CountryPhoneInput #

A ready-made phone-number text field with an embedded country flag/code selector and automatic mask formatting.

CountryPhoneInput(
  initialCountry: Country.ru(),
  placeholder: 'Phone number',
  showPhoneCode: true,
  onChanged: (String value) {
    debugPrint('Phone: $value');
  },
  onCountryChanged: (Country country) {
    debugPrint('Country: ${country.displayName}');
  },
);

Use CountryPhoneInput.extended for additional configuration (overflow notifiers, custom scroll sizes, etc.).

CountryPhoneController #

An extension type over ValueNotifier<String> that manages the phone number state with helpers for extracting the country ISO2 code and raw subscriber number.

// Create with an initial value
final controller = CountryPhoneController.apply('+7 123 456 78 90');

print(controller.phone);       // +71234567890
print(controller.number);      // 1234567890
print(controller.countryCode); // RU

// Or start empty
final emptyController = CountryPhoneController.empty();

Pass the controller to CountryPhoneInput:

CountryPhoneInput(
  controller: controller,
);

CountryInputFormatter #

A TextInputFormatter that formats input according to a phone mask. Supports lazy (default) and eager completion modes. When the input exceeds the mask length, the formatter switches to flat mode (digits only) and fires onOverflowChanged.

CountryInputFormatter(
  mask: '000 000-00-00',
  onOverflowChanged: (bool isOverflow) {
    debugPrint('Overflow: $isOverflow');
  },
)
Symbol Matches
0 digit [0-9]
# digit [0-9]
A digit [0-9]

CountryScope #

An InheritedWidget that pre-loads and provides the country list to its subtree, avoiding repeated async loading.

CountryScope(
  exclude: const ['RU'],
  child: MyApp(),
)

Access from descendants:

// Get the controller
final controller = CountryScope.of(context);

// Get the list of countries (subscribes to changes)
final countries = CountryScope.countriesOf(context);

// Look up a country by ISO2 code
final country = CountryScope.getCountryByCode(context, 'US');

Set lazy: true to defer the country-list load until you trigger it explicitly — useful when the list is only needed behind a navigation gate:

CountryScope(
  lazy: true,
  child: Builder(
    builder: (context) {
      // Loading starts here, not on CountryScope creation.
      CountryScope.of(context).getCountries();
      return const MyCountryPage();
    },
  ),
)

CountryPickerTheme #

A ThemeExtension for full visual customization. Register it in your MaterialApp theme:

MaterialApp(
  theme: ThemeData(
    extensions: [
      CountryPickerTheme(
        backgroundColor: Colors.white,
        onBackgroundColor: Colors.black87,
        secondaryBackgroundColor: Colors.grey.shade100,
        onSecondaryBackgroundColor: Colors.black54,
        accentColor: Colors.blue,
        barrierColor: Colors.black54,
        dividerColor: Colors.grey.shade300,
        textStyle: const TextStyle(fontSize: 16),
        secondaryTextStyle: const TextStyle(fontSize: 13),
        searchTextStyle: const TextStyle(fontSize: 14),
        flagSize: 22,
        inputHeight: 56,
        padding: 16,
        indent: 10,
        radius: 12,
      ),
    ],
  ),
);

All Countries List #

See the All Countries List on the wiki.

Changelog #

See CHANGELOG.md for all release notes.

Maintainers #

Anton Ustinoff (ziqq)

Funding #

If you want to support the development of this library:

License #

MIT

Coverage #

2
likes
160
points
742
downloads

Publisher

unverified uploader

Weekly Downloads

An easy-to-use country selection widget for Flutter. Allows users to select a country from a comprehensive list. Supports Android, iOS, web, Windows and Linux platforms.

Repository (GitHub)
View/report issues
Contributing

Topics

#country #picker #phone #input

Documentation

API reference

Funding

Consider supporting this project:

www.buymeacoffee.com
boosty.to

License

MIT (license)

Dependencies

collection, flutter, meta

More

Packages that depend on flutter_simple_country_picker