Country Flags Widget
A powerful Flutter package for displaying country flags using images from flagcdn.com with advanced features and optimizations.
Features
- 🚀 Cached Network Images: Better performance with offline support
- 🌍 249+ Countries: Complete database of ISO alpha-2 country codes
- 📏 Multiple Sizes: 6 different flag sizes (w20, w40, w80, w160, w320, w640)
- ✨ Shimmer Loading: Beautiful loading animations
- ✅ Validation: Built-in country code validation with custom error messages
- 🎨 Customizable: Size, fit, border radius, decoration, and more
- 🔄 Auto Normalization: Automatic country code normalization (uppercase to lowercase)
- 🛡️ Error Handling: Comprehensive error handling with fallback widgets
- 📱 Memory Optimized: Efficient memory usage with cache optimization
- 🧪 Well Tested: Comprehensive unit tests for all features
Installation
Option 1: GitHub Packages (Recommended)
Add this to your pubspec.yaml:
dependencies:
country_flags_world:
git:
url: https://github.com/creyt2012/country_flags_world.git
ref: v2.0.3
Option 2: Pub.dev (if available)
dependencies:
country_flags_world: ^2.0.3
Then run:
flutter pub get
Usage
Basic Usage
import 'package:country_flags_world/country_flags.dart';
CountryFlag(
countryCode: 'us',
)
CountryFlag(
countryCode: 'vn',
width: 100,
height: 75,
)
Predefined Sizes
CountryFlag.small(countryCode: 'us') // 20x13
CountryFlag.medium(countryCode: 'vn') // 40x27
CountryFlag.large(countryCode: 'fr') // 80x53
CountryFlag.extraLarge(countryCode: 'de') // 160x107
Custom Flag Sizes
CountryFlag(
countryCode: 'jp',
flagSize: FlagSize.huge, // 320x213
width: 100,
height: 67,
)
Advanced Customization
CountryFlag(
countryCode: 'jp',
width: 150,
height: 100,
fit: BoxFit.cover,
borderRadius: BorderRadius.circular(8),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.1),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
)
Custom Loading and Error States
CountryFlag(
countryCode: 'de',
placeholder: Container(
color: Colors.grey[200],
child: const Center(
child: CircularProgressIndicator(),
),
),
fallback: Container(
color: Colors.grey[300],
child: const Center(
child: Icon(Icons.flag, color: Colors.grey),
),
),
)
Disable Loading Indicator
CountryFlag(
countryCode: 'it',
showLoadingIndicator: false,
)
Custom Loading Indicator Color
CountryFlag(
countryCode: 'es',
loadingIndicatorColor: Colors.blue,
)
Shimmer Loading Effect
CountryFlag(
countryCode: 'it',
showShimmer: true,
shimmerColor: Colors.blue,
)
Country Code Validation
// Default validation (shows error for invalid codes)
CountryFlag(countryCode: 'invalid')
// Disable validation
CountryFlag(
countryCode: 'invalid',
validateCountryCode: false,
)
// Custom error message
CountryFlag(
countryCode: 'invalid',
invalidCountryCodeMessage: 'Country not found',
)
Using CountryHelper
import 'package:country_flags_world/country_flags.dart';
// Validate country code
bool isValid = CountryHelper.isValidCountryCode('us'); // true
// Get country name
String? name = CountryHelper.getCountryName('vn'); // 'Vietnam'
// Get flag URL
String url = CountryHelper.getFlagUrl('fr', size: 'w160');
// Get all available flag sizes
List<String> sizes = CountryHelper.availableFlagSizes;
SVG Support (mới)
CountryFlag(
countryCode: 'us',
useSvg: true, // dùng SVG để hiển thị sắc nét ở mọi kích thước
)
Country Flag with Name (mới)
// Hiển thị cờ cùng tên quốc gia
CountryFlagWithName(
countryCode: 'us',
flagWidth: 40,
flagHeight: 27,
)
// Layout dọc
CountryFlagWithName(
countryCode: 'vn',
direction: Axis.vertical,
alignment: MainAxisAlignment.center,
)
// Tùy chỉnh style text
CountryFlagWithName(
countryCode: 'fr',
countryNameStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.blue,
),
spacing: 12.0,
)
// Các kích thước có sẵn
CountryFlagWithName.small(countryCode: 'us')
CountryFlagWithName.medium(countryCode: 'vn')
CountryFlagWithName.large(countryCode: 'fr')
CountryFlagWithName.extraLarge(countryCode: 'de')
Flag Shapes (mới)
// Hình chữ nhật (mặc định)
CountryFlag(countryCode: 'us', shape: FlagShape.rectangle)
// Hình tròn
CountryFlag(countryCode: 'vn', shape: FlagShape.circle)
// Hình vuông
CountryFlag(countryCode: 'fr', shape: FlagShape.square)
// Hình vuông bo tròn
CountryFlag(countryCode: 'de', shape: FlagShape.roundedSquare)
// Hình chữ nhật bo tròn
CountryFlag(countryCode: 'jp', shape: FlagShape.rounded)
// Hình stadium (bo tròn nhiều)
CountryFlag(countryCode: 'it', shape: FlagShape.stadium)
// Hình kim cương
CountryFlag(countryCode: 'es', shape: FlagShape.diamond)
// Hình kim cương bo tròn
CountryFlag(countryCode: 'ca', shape: FlagShape.roundedDiamond)
// Kết hợp với tên quốc gia
CountryFlagWithName(
countryCode: 'us',
shape: FlagShape.circle,
flagWidth: 60,
flagHeight: 60,
)
Country Codes
The package uses ISO alpha-2 country codes. Here are some examples:
us- United Statesvn- Vietnamfr- Francede- Germanyjp- Japangb- United Kingdomca- Canadaau- Australiabr- Brazilin- India
Note: Country codes are automatically converted to lowercase, so both 'US' and 'us' will work.
API Reference
CountryFlag
A widget that displays a country flag using images from flagcdn.com.
Constructors
CountryFlag()- Creates a country flag with custom parametersCountryFlag.small()- Creates a small flag (20x13)CountryFlag.medium()- Creates a medium flag (40x27)CountryFlag.large()- Creates a large flag (80x53)CountryFlag.extraLarge()- Creates an extra large flag (160x107)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
countryCode |
String |
required | ISO alpha-2 country code |
width |
double? |
null | Width of the flag |
height |
double? |
null | Height of the flag |
flagSize |
FlagSize? |
null | Flag size from flagcdn.com |
fit |
BoxFit? |
BoxFit.cover |
How to fit the image |
borderRadius |
BorderRadius? |
null | Border radius of the flag |
decoration |
BoxDecoration? |
null | Decoration for the container |
placeholder |
Widget? |
null | Widget to show while loading |
fallback |
Widget? |
null | Widget to show on error |
showLoadingIndicator |
bool |
true |
Whether to show loading indicator |
loadingIndicatorColor |
Color? |
null | Color of loading indicator |
showShimmer |
bool |
true |
Whether to show shimmer effect |
shimmerColor |
Color? |
null | Color of shimmer effect |
validateCountryCode |
bool |
true |
Whether to validate country code |
invalidCountryCodeMessage |
String? |
null | Custom error message for invalid codes |
CountryHelper
A utility class for country code validation and country information.
Methods
| Method | Return Type | Description |
|---|---|---|
isValidCountryCode(String code) |
bool |
Validates if country code is valid |
normalizeCountryCode(String code) |
String |
Normalizes country code to lowercase |
getCountryName(String code) |
String? |
Gets country name from code |
getFlagUrl(String code, {String size}) |
String |
Gets flag URL for country code |
getAllFlagUrls(String code) |
Map<String, String> |
Gets all flag URLs for country |
Properties
| Property | Type | Description |
|---|---|---|
allCountryCodes |
Set<String> |
All valid country codes |
allCountryNames |
Map<String, String> |
All country names |
availableFlagSizes |
List<String> |
Available flag sizes |
FlagSize
Enum for flag sizes available from flagcdn.com.
Values
| Value | Size | Width | Height |
|---|---|---|---|
FlagSize.small |
w20 | 20px | 13px |
FlagSize.medium |
w40 | 40px | 27px |
FlagSize.large |
w80 | 80px | 53px |
FlagSize.extraLarge |
w160 | 160px | 107px |
FlagSize.huge |
w320 | 320px | 213px |
FlagSize.extraHuge |
w640 | 640px | 427px |
Example App
Here's a complete example showing different ways to use the package:
import 'package:flutter/material.dart';
import 'package:country_flags_widget/country_flags.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Country Flags Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Country Flags Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Basic Flags:',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
Row(
children: [
CountryFlag.small(countryCode: 'us'),
const SizedBox(width: 16),
CountryFlag.small(countryCode: 'vn'),
const SizedBox(width: 16),
CountryFlag.small(countryCode: 'fr'),
const SizedBox(width: 16),
CountryFlag.small(countryCode: 'de'),
],
),
const SizedBox(height: 32),
const Text(
'Different Sizes:',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
Row(
children: [
CountryFlag.small(countryCode: 'jp'),
const SizedBox(width: 16),
CountryFlag.medium(countryCode: 'jp'),
const SizedBox(width: 16),
CountryFlag.large(countryCode: 'jp'),
],
),
const SizedBox(height: 32),
const Text(
'Custom Styling:',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
CountryFlag(
countryCode: 'it',
width: 120,
height: 80,
borderRadius: BorderRadius.circular(12),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.1),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
),
],
),
),
);
}
}
License
This package is licensed under the MIT License. See the LICENSE file for details.
Author
- Website: https://algonest.io.vn
Copyright: Perpetual, unlimited use granted
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Issues
If you find any issues or have feature requests, please create an issue.