flutter_simple_country_picker 0.8.0
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 #

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.supportedLocalestosupportedLocalesto 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 #
Funding #
If you want to support the development of this library: