From 47ea3884c9ab96296aae644570b875cece416bb4 Mon Sep 17 00:00:00 2001 From: Ahmed Elsayed Date: Thu, 16 May 2024 22:04:08 +0300 Subject: [PATCH 1/2] Always call onChanged when tapping enabled item --- packages/dropdown_button2/lib/src/dropdown_button2.dart | 5 +---- packages/dropdown_button2/lib/src/dropdown_menu_item.dart | 1 + packages/dropdown_button2/lib/src/dropdown_route.dart | 2 ++ 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/dropdown_button2/lib/src/dropdown_button2.dart b/packages/dropdown_button2/lib/src/dropdown_button2.dart index ac1627b..c530117 100644 --- a/packages/dropdown_button2/lib/src/dropdown_button2.dart +++ b/packages/dropdown_button2/lib/src/dropdown_button2.dart @@ -582,6 +582,7 @@ class _DropdownButton2State extends State> buttonRect: _rect, selectedIndex: _selectedIndex ?? 0, isNoSelectedItem: _selectedIndex == null, + onChanged: widget.onChanged, capturedThemes: InheritedTheme.capture(from: context, to: navigator.context), style: _textStyle!, @@ -611,10 +612,6 @@ class _DropdownButton2State extends State> _removeDropdownRoute(); _isMenuOpen.value = false; widget.onMenuStateChange?.call(false); - if (!mounted || newValue == null) { - return; - } - widget.onChanged?.call(newValue.result); }); widget.onMenuStateChange?.call(true); diff --git a/packages/dropdown_button2/lib/src/dropdown_menu_item.dart b/packages/dropdown_button2/lib/src/dropdown_menu_item.dart index ac85800..aea156a 100644 --- a/packages/dropdown_button2/lib/src/dropdown_menu_item.dart +++ b/packages/dropdown_button2/lib/src/dropdown_menu_item.dart @@ -175,6 +175,7 @@ class _DropdownItemButtonState extends State<_DropdownItemButton> { final DropdownItem dropdownItem = widget.route.items[widget.itemIndex]; dropdownItem.onTap?.call(); + widget.route.onChanged?.call(dropdownItem.value); if (dropdownItem.closeOnTap) { Navigator.pop( diff --git a/packages/dropdown_button2/lib/src/dropdown_route.dart b/packages/dropdown_button2/lib/src/dropdown_route.dart index f114b72..757261b 100644 --- a/packages/dropdown_button2/lib/src/dropdown_route.dart +++ b/packages/dropdown_button2/lib/src/dropdown_route.dart @@ -6,6 +6,7 @@ class _DropdownRoute extends PopupRoute<_DropdownRouteResult> { required this.buttonRect, required this.selectedIndex, required this.isNoSelectedItem, + required this.onChanged, required this.capturedThemes, required this.style, required this.barrierDismissible, @@ -29,6 +30,7 @@ class _DropdownRoute extends PopupRoute<_DropdownRouteResult> { final ValueNotifier buttonRect; final int selectedIndex; final bool isNoSelectedItem; + final ValueChanged? onChanged; final CapturedThemes capturedThemes; final TextStyle style; final FocusNode parentFocusNode; From e3bfb35fde8beea48dc80d0e71d564e7fd47a667 Mon Sep 17 00:00:00 2001 From: Ahmed Elsayed Date: Thu, 16 May 2024 22:09:43 +0300 Subject: [PATCH 2/2] Update MultiSelectExample --- README.md | 64 +++++++++---------- .../lib/src/multi_select_example.dart | 64 +++++++++---------- 2 files changed, 62 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index ad1fc13..26dcf02 100644 --- a/README.md +++ b/README.md @@ -453,44 +453,30 @@ Widget build(BuildContext context) { return DropdownItem( value: item, height: 40, - //disable default onTap to avoid closing menu when selecting an item - enabled: false, + closeOnTap: false, child: ValueListenableBuilder>( valueListenable: multiValueListenable, builder: (context, multiValue, _) { final isSelected = multiValue.contains(item); - return InkWell( - onTap: () { - if (item == 'All') { - isSelected - ? multiValueListenable.value = [] - : multiValueListenable.value = List.from(items); - } else { - multiValueListenable.value = isSelected - ? ([...multiValue]..remove(item)) - : [...multiValue, item]; - } - }, - child: Container( - height: double.infinity, - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: Row( - children: [ - if (isSelected) - const Icon(Icons.check_box_outlined) - else - const Icon(Icons.check_box_outline_blank), - const SizedBox(width: 16), - Expanded( - child: Text( - item, - style: const TextStyle( - fontSize: 14, - ), + return Container( + height: double.infinity, + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Row( + children: [ + if (isSelected) + const Icon(Icons.check_box_outlined) + else + const Icon(Icons.check_box_outline_blank), + const SizedBox(width: 16), + Expanded( + child: Text( + item, + style: const TextStyle( + fontSize: 14, ), ), - ], - ), + ), + ], ), ); }, @@ -498,7 +484,19 @@ Widget build(BuildContext context) { ); }).toList(), multiValueListenable: multiValueListenable, - onChanged: (value) {}, + onChanged: (value) { + final multiValue = multiValueListenable.value; + final isSelected = multiValue.contains(value); + if (value == 'All') { + isSelected + ? multiValueListenable.value = [] + : multiValueListenable.value = List.from(items); + } else { + multiValueListenable.value = isSelected + ? ([...multiValue]..remove(value)) + : [...multiValue, value!]; + } + }, selectedItemBuilder: (context) { return items.map( (item) { diff --git a/packages/dropdown_button2_test/lib/src/multi_select_example.dart b/packages/dropdown_button2_test/lib/src/multi_select_example.dart index d510cb5..240e268 100644 --- a/packages/dropdown_button2_test/lib/src/multi_select_example.dart +++ b/packages/dropdown_button2_test/lib/src/multi_select_example.dart @@ -36,44 +36,30 @@ class _MultiSelectExampleState extends State { return DropdownItem( value: item, height: 40, - //disable default onTap to avoid closing menu when selecting an item - enabled: false, + closeOnTap: false, child: ValueListenableBuilder>( valueListenable: multiValueListenable, builder: (context, multiValue, _) { final isSelected = multiValue.contains(item); - return InkWell( - onTap: () { - if (item == 'All') { - isSelected - ? multiValueListenable.value = [] - : multiValueListenable.value = List.from(items); - } else { - multiValueListenable.value = isSelected - ? ([...multiValue]..remove(item)) - : [...multiValue, item]; - } - }, - child: Container( - height: double.infinity, - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: Row( - children: [ - if (isSelected) - const Icon(Icons.check_box_outlined) - else - const Icon(Icons.check_box_outline_blank), - const SizedBox(width: 16), - Expanded( - child: Text( - item, - style: const TextStyle( - fontSize: 14, - ), + return Container( + height: double.infinity, + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Row( + children: [ + if (isSelected) + const Icon(Icons.check_box_outlined) + else + const Icon(Icons.check_box_outline_blank), + const SizedBox(width: 16), + Expanded( + child: Text( + item, + style: const TextStyle( + fontSize: 14, ), ), - ], - ), + ), + ], ), ); }, @@ -81,7 +67,19 @@ class _MultiSelectExampleState extends State { ); }).toList(), multiValueListenable: multiValueListenable, - onChanged: (value) {}, + onChanged: (value) { + final multiValue = multiValueListenable.value; + final isSelected = multiValue.contains(value); + if (value == 'All') { + isSelected + ? multiValueListenable.value = [] + : multiValueListenable.value = List.from(items); + } else { + multiValueListenable.value = isSelected + ? ([...multiValue]..remove(value)) + : [...multiValue, value!]; + } + }, selectedItemBuilder: (context) { return items.map( (item) {