From cbfca0de133e4d51a650055e7d1602ce03a234a4 Mon Sep 17 00:00:00 2001 From: rsanjuan87 Date: Fri, 9 Jun 2023 15:53:23 +0200 Subject: [PATCH 1/5] Added dialog mode feature --- example/.gitignore | 11 ++- example/.metadata | 39 +++++++- example/android/.gitignore | 6 ++ example/ios/.gitignore | 2 + example/lib/main.dart | 125 +++++++++++++++++-------- lib/country_picker.dart | 2 + lib/src/country_list_bottom_sheet.dart | 87 ++++++++++++----- 7 files changed, 202 insertions(+), 70 deletions(-) diff --git a/example/.gitignore b/example/.gitignore index 1ba9c33..24476c5 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -8,6 +8,7 @@ .buildlog/ .history .svn/ +migrate_working_dir/ # IntelliJ related *.iml @@ -22,6 +23,7 @@ # Flutter/Dart/Pub related **/doc/api/ +**/ios/Flutter/.last_build_id .dart_tool/ .flutter-plugins .flutter-plugins-dependencies @@ -30,14 +32,13 @@ .pub/ /build/ -# Web related -lib/generated_plugin_registrant.dart - # Symbolication related app.*.symbols # Obfuscation related app.*.map.json -# Exceptions to above rules. -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/example/.metadata b/example/.metadata index ade6bc9..f25b3d4 100644 --- a/example/.metadata +++ b/example/.metadata @@ -1,10 +1,45 @@ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # -# This file should be version controlled and should not be manually edited. +# This file should be version controlled. version: - revision: 8af6b2f038c1172e61d418869363a28dffec3cb4 + revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf channel: stable project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + - platform: android + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + - platform: ios + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + - platform: linux + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + - platform: macos + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + - platform: web + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + - platform: windows + create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/example/android/.gitignore b/example/android/.gitignore index bc2100d..6f56801 100644 --- a/example/android/.gitignore +++ b/example/android/.gitignore @@ -5,3 +5,9 @@ gradle-wrapper.jar /gradlew.bat /local.properties GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +**/*.keystore +**/*.jks diff --git a/example/ios/.gitignore b/example/ios/.gitignore index e96ef60..7a7f987 100644 --- a/example/ios/.gitignore +++ b/example/ios/.gitignore @@ -1,3 +1,4 @@ +**/dgph *.mode1v3 *.mode2v3 *.moved-aside @@ -18,6 +19,7 @@ Flutter/App.framework Flutter/Flutter.framework Flutter/Flutter.podspec Flutter/Generated.xcconfig +Flutter/ephemeral/ Flutter/app.flx Flutter/app.zip Flutter/flutter_assets/ diff --git a/example/lib/main.dart b/example/lib/main.dart index 7758990..d62bc12 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -62,45 +62,96 @@ class HomePage extends StatelessWidget { return Scaffold( appBar: AppBar(title: Text('Demo for country picker')), body: Center( - child: ElevatedButton( - onPressed: () { - showCountryPicker( - context: context, - //Optional. Can be used to exclude(remove) one ore more country from the countries list (optional). - exclude: ['KN', 'MF'], - favorite: ['SE'], - //Optional. Shows phone code before the country name. - showPhoneCode: true, - onSelect: (Country country) { - print('Select country: ${country.displayName}'); - }, - // Optional. Sets the theme for the country list picker. - countryListTheme: CountryListThemeData( - // Optional. Sets the border radius for the bottomsheet. - borderRadius: BorderRadius.only( - topLeft: Radius.circular(40.0), - topRight: Radius.circular(40.0), - ), - // Optional. Styles the search field. - inputDecoration: InputDecoration( - labelText: 'Search', - hintText: 'Start typing to search', - prefixIcon: const Icon(Icons.search), - border: OutlineInputBorder( - borderSide: BorderSide( - color: const Color(0xFF8C98A8).withOpacity(0.2), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: ElevatedButton( + onPressed: () { + showCountryPicker( + context: context, + //Optional. Can be used to exclude(remove) one ore more country from the countries list (optional). + exclude: ['KN', 'MF'], + favorite: ['SE'], + //Optional. Shows phone code before the country name. + showPhoneCode: true, + onSelect: (Country country) { + print('Select country: ${country.displayName}'); + }, + // Optional. Sets the theme for the country list picker. + countryListTheme: CountryListThemeData( + // Optional. Sets the border radius for the bottomsheet. + borderRadius: BorderRadius.only( + topLeft: Radius.circular(40.0), + topRight: Radius.circular(40.0), + ), + // Optional. Styles the search field. + inputDecoration: InputDecoration( + labelText: 'Search', + hintText: 'Start typing to search', + prefixIcon: const Icon(Icons.search), + border: OutlineInputBorder( + borderSide: BorderSide( + color: const Color(0xFF8C98A8).withOpacity(0.2), + ), + ), + ), + // Optional. Styles the text in the search field + searchTextStyle: TextStyle( + color: Colors.blue, + fontSize: 18, + ), ), - ), - ), - // Optional. Styles the text in the search field - searchTextStyle: TextStyle( - color: Colors.blue, - fontSize: 18, - ), + ); + }, + child: const Text('Show country picker bottom sheet'), ), - ); - }, - child: const Text('Show country picker'), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: ElevatedButton( + onPressed: () { + showCountryPicker( + context: context, + //Optional. Can be used to exclude(remove) one ore more country from the countries list (optional). + exclude: ['KN', 'MF'], + favorite: ['SE'], + //Optional. Shows phone code before the country name. + showPhoneCode: true, + onSelect: (Country country) { + print('Select country: ${country.displayName}'); + }, + // Optional. Sets the theme for the country list picker. + countryListTheme: CountryListThemeData( + // Optional. Sets the border radius for the bottomsheet. + borderRadius: BorderRadius.all( + Radius.circular(40.0), + ), + // Optional. Styles the search field. + inputDecoration: InputDecoration( + labelText: 'Search', + hintText: 'Start typing to search', + prefixIcon: const Icon(Icons.search), + border: OutlineInputBorder( + borderSide: BorderSide( + color: const Color(0xFF8C98A8).withOpacity(0.2), + ), + ), + ), + // Optional. Styles the text in the search field + searchTextStyle: TextStyle( + color: Colors.blue, + fontSize: 18, + ), + ), + dialogMode: true, + ); + }, + child: const Text('Show country picker dialog'), + ), + ), + ], ), ), ); diff --git a/lib/country_picker.dart b/lib/country_picker.dart index 9250998..19c191c 100644 --- a/lib/country_picker.dart +++ b/lib/country_picker.dart @@ -55,6 +55,7 @@ void showCountryPicker({ bool showWorldWide = false, bool showSearch = true, bool useSafeArea = false, + bool dialogMode = false, }) { assert( exclude == null || countryFilter == null, @@ -73,5 +74,6 @@ void showCountryPicker({ showWorldWide: showWorldWide, showSearch: showSearch, useSafeArea: useSafeArea, + dialogMode: dialogMode, ); } diff --git a/lib/src/country_list_bottom_sheet.dart b/lib/src/country_list_bottom_sheet.dart index edf1df8..db80b10 100644 --- a/lib/src/country_list_bottom_sheet.dart +++ b/lib/src/country_list_bottom_sheet.dart @@ -17,27 +17,67 @@ void showCountryListBottomSheet({ bool showWorldWide = false, bool showSearch = true, bool useSafeArea = false, + bool dialogMode = false, }) { - showModalBottomSheet( - context: context, - isScrollControlled: true, - backgroundColor: Colors.transparent, - useSafeArea: useSafeArea, - builder: (context) => _builder( - context, - onSelect, - favorite, - exclude, - countryFilter, - showPhoneCode, - countryListTheme, - searchAutofocus, - showWorldWide, - showSearch, - ), - ).whenComplete(() { - if (onClosed != null) onClosed(); - }); + if (dialogMode) { + showDialog( + context: context, + builder: (context) { + return Center( + child: SizedBox( + height: getHeight(context, countryListTheme), + width: MediaQuery.of(context).size.width * .7, + child: Material( + color: Colors.transparent, + child: _builder( + context, + onSelect, + favorite, + exclude, + countryFilter, + showPhoneCode, + countryListTheme, + searchAutofocus, + showWorldWide, + showSearch, + ), + ), + ), + ); + }, + ).whenComplete(() { + if (onClosed != null) onClosed(); + }); + } else { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + useSafeArea: useSafeArea, + builder: (context) => _builder( + context, + onSelect, + favorite, + exclude, + countryFilter, + showPhoneCode, + countryListTheme, + searchAutofocus, + showWorldWide, + showSearch, + ), + ).whenComplete(() { + if (onClosed != null) onClosed(); + }); + } +} + +double getHeight(BuildContext context, CountryListThemeData? countryListTheme) { + final device = MediaQuery.of(context).size.height; + final statusBarHeight = MediaQuery.of(context).padding.top; + final height = countryListTheme?.bottomSheetHeight ?? + device - (statusBarHeight + (kToolbarHeight / 1.5)); + return height; } Widget _builder( @@ -52,11 +92,6 @@ Widget _builder( bool showWorldWide, bool showSearch, ) { - final device = MediaQuery.of(context).size.height; - final statusBarHeight = MediaQuery.of(context).padding.top; - final height = countryListTheme?.bottomSheetHeight ?? - device - (statusBarHeight + (kToolbarHeight / 1.5)); - Color? _backgroundColor = countryListTheme?.backgroundColor ?? Theme.of(context).bottomSheetTheme.backgroundColor; if (_backgroundColor == null) { @@ -74,7 +109,7 @@ Widget _builder( ); return Container( - height: height, + height: getHeight(context, countryListTheme), padding: countryListTheme?.padding, margin: countryListTheme?.margin, decoration: BoxDecoration( From 80772fea0cdab282d157e03a0988d4242b79663d Mon Sep 17 00:00:00 2001 From: rsanjuan87 Date: Fri, 9 Jun 2023 16:42:13 +0200 Subject: [PATCH 2/5] added attr weight --- example/lib/main.dart | 2 ++ lib/src/country_list_bottom_sheet.dart | 8 ++++++-- lib/src/country_list_theme_data.dart | 9 ++++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index d62bc12..7fd9d80 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -144,6 +144,8 @@ class HomePage extends StatelessWidget { color: Colors.blue, fontSize: 18, ), + height: 300, + weight: 300, ), dialogMode: true, ); diff --git a/lib/src/country_list_bottom_sheet.dart b/lib/src/country_list_bottom_sheet.dart index db80b10..825ce16 100644 --- a/lib/src/country_list_bottom_sheet.dart +++ b/lib/src/country_list_bottom_sheet.dart @@ -26,7 +26,7 @@ void showCountryListBottomSheet({ return Center( child: SizedBox( height: getHeight(context, countryListTheme), - width: MediaQuery.of(context).size.width * .7, + width: getWeight(context, countryListTheme), child: Material( color: Colors.transparent, child: _builder( @@ -75,11 +75,15 @@ void showCountryListBottomSheet({ double getHeight(BuildContext context, CountryListThemeData? countryListTheme) { final device = MediaQuery.of(context).size.height; final statusBarHeight = MediaQuery.of(context).padding.top; - final height = countryListTheme?.bottomSheetHeight ?? + final height = countryListTheme?.height ?? device - (statusBarHeight + (kToolbarHeight / 1.5)); return height; } +double getWeight(BuildContext context, CountryListThemeData? countryListTheme) { + return countryListTheme?.weight ?? MediaQuery.of(context).size.width * .7; +} + Widget _builder( BuildContext context, ValueChanged onSelect, diff --git a/lib/src/country_list_theme_data.dart b/lib/src/country_list_theme_data.dart index 7153d3d..1d7e78a 100644 --- a/lib/src/country_list_theme_data.dart +++ b/lib/src/country_list_theme_data.dart @@ -34,7 +34,7 @@ class CountryListThemeData { ///Country list modal height /// /// By default it's fullscreen - final double? bottomSheetHeight; + final double? height; /// the padding of the bottom sheet final EdgeInsets? padding; @@ -42,6 +42,8 @@ class CountryListThemeData { /// the margin of the bottom sheet final EdgeInsets? margin; + final double? weight; + const CountryListThemeData({ this.backgroundColor, this.textStyle, @@ -49,8 +51,9 @@ class CountryListThemeData { this.flagSize, this.inputDecoration, this.borderRadius, - this.bottomSheetHeight, + this.height, this.padding, - this.margin, + this.margin, + this.weight, }); } From 2ce749ee8d8e2837aa7696f02444b47f7d0787e1 Mon Sep 17 00:00:00 2001 From: rsanjuan87 Date: Fri, 9 Jun 2023 18:04:16 +0200 Subject: [PATCH 3/5] added filter favorites remove favorites from normal list --- lib/src/country_list_view.dart | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/src/country_list_view.dart b/lib/src/country_list_view.dart index 7053b34..f99c62a 100644 --- a/lib/src/country_list_view.dart +++ b/lib/src/country_list_view.dart @@ -149,7 +149,7 @@ class _CountryListViewState extends State { child: ListView( children: [ if (_favoriteList != null) ...[ - ..._favoriteList! + ..._favoriteFilteredList! .map((currency) => _listRow(currency)) .toList(), const Padding( @@ -158,6 +158,7 @@ class _CountryListViewState extends State { ), ], ..._filteredList + .where((e) => !(_favoriteFilteredList?.contains(e) ?? false)) .map((country) => _listRow(country)) .toList(), ], @@ -167,6 +168,15 @@ class _CountryListViewState extends State { ); } + List? get _favoriteFilteredList => _favoriteList + ?.where( + (c) => c.startsWith( + _searchController.text, + CountryLocalizations.of(context), + ), + ) + .toList(); + Widget _listRow(Country country) { final TextStyle _textStyle = widget.countryListTheme?.textStyle ?? _defaultTextStyle; From 9cf9013d24460cc4eb5ce26c3b9a8409bc22cce3 Mon Sep 17 00:00:00 2001 From: rsanjuan87 Date: Mon, 12 Jun 2023 09:23:57 +0200 Subject: [PATCH 4/5] Add Cuba to favorite countries list in country picker widget. --- example/lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 7fd9d80..0105013 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -116,7 +116,7 @@ class HomePage extends StatelessWidget { context: context, //Optional. Can be used to exclude(remove) one ore more country from the countries list (optional). exclude: ['KN', 'MF'], - favorite: ['SE'], + favorite: ['SE', 'CU'], //Optional. Shows phone code before the country name. showPhoneCode: true, onSelect: (Country country) { From d13172a584e4f595043f057e983c40f26b3c9396 Mon Sep 17 00:00:00 2001 From: rsanjuan87 Date: Thu, 29 Jun 2023 12:51:37 +0200 Subject: [PATCH 5/5] Refactor _flagWidget method to pass a TextStyle parameter for consistent styling. --- lib/src/country_list_view.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/country_list_view.dart b/lib/src/country_list_view.dart index f99c62a..df84dcc 100644 --- a/lib/src/country_list_view.dart +++ b/lib/src/country_list_view.dart @@ -202,7 +202,7 @@ class _CountryListViewState extends State { Row( children: [ const SizedBox(width: 20), - _flagWidget(country), + _flagWidget(country, _textStyle), if (widget.showPhoneCode && !country.iswWorldWide) ...[ const SizedBox(width: 15), SizedBox( @@ -233,7 +233,7 @@ class _CountryListViewState extends State { ); } - Widget _flagWidget(Country country) { + Widget _flagWidget(Country country, TextStyle textStyle) { final bool isRtl = Directionality.of(context) == TextDirection.rtl; return SizedBox( // the conditional 50 prevents irregularities caused by the flags in RTL mode @@ -242,7 +242,7 @@ class _CountryListViewState extends State { country.iswWorldWide ? '\uD83C\uDF0D' : Utils.countryCodeToEmoji(country.countryCode), - style: TextStyle( + style: textStyle.copyWith( fontSize: widget.countryListTheme?.flagSize ?? 25, ), ),