oi-narendra / multiselect-dropdown

Streamlined Flutter widget for versatile multi-selection with extensive customization.
https://pub.dev/packages/multi_dropdown
GNU General Public License v3.0
74 stars 84 forks source link

Having some issues on desktop plaforms #89

Open kartikey321 opened 7 months ago

kartikey321 commented 7 months ago

I am facing some issues on desktop platforms using this library. In a screen I have used a gridview to wrap 5-6 Multiselect dropdowns

CASE 1: When i click on the first dropdown and then select any options and tap outside , everthing is working perfectly as it should. CASE 2: Now suppose there is a textfield before the the first gridview and i click on the textfield and press TAB key to navigate all the nest textfields and dropdown, it is again working perfectly and as i press tab each dropdown is opening and closing as i press next tab, but i cannot access options from there using up and down keys but it is a separate thing and not much necessary.

NOW THE ISSUE ARISES

CASE 3: Now when i click on the first dropdown and then press TAB key to navigate , the first dropdown overlay is not closing and now when it is stuck you cannot make it unstuck by clicking on the screen. I did some debugging there , i can see the hasFocus value changing but still the overlay remains opened and cannot be closed

Now if i pop this screen the overlay that was stuck moves to the top left of the screen and it can only be fixed by hot-restart

Is there any fix to it?

Minimalistic code to show the error

return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: MasonryGridView(
        mainAxisSpacing: 10,
        crossAxisSpacing: 3,
        shrinkWrap: true,
        physics: const NeverScrollableScrollPhysics(),
        gridDelegate: const SliverSimpleGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3),
        children: [
          TextField(),
          for (int i = 0; i < 12; i++)
            MultiSelectDropDown(
              onOptionSelected: (List<ValueItem> selectedOptions) {},
              options: const <ValueItem>[
                ValueItem(label: 'Option 1', value: '1'),
                ValueItem(label: 'Option 2', value: '2'),
                ValueItem(label: 'Option 3', value: '3'),
                ValueItem(label: 'Option 4', value: '4'),
                ValueItem(label: 'Option 5', value: '5'),
                ValueItem(label: 'Option 6', value: '6'),
              ],
              selectionType: SelectionType.single,
              chipConfig: const ChipConfig(wrapType: WrapType.wrap),
              dropdownHeight: 300,
              optionTextStyle: const TextStyle(fontSize: 16),
              selectedOptionIcon: const Icon(Icons.check_circle),
            )
        ],
      ),
    ); 
asmit-gupta commented 7 months ago

I encountered a recurring problem while utilizing the MultiSelectDropDown widget within my Flutter application. Specifically, when I select certain options and subsequently press the ‘TAB’ key, the entire interface becomes unresponsive, necessitating a complete app reload to restore functionality.

kartikey321 commented 7 months ago

I am trying to debug it FOR DEBUGGING, I have reduced the no of dropdowns to 5 and added Dropdown_$i to every option to distinguish between dropdowns

 MultiSelectDropDown(
              onOptionSelected: (List<ValueItem> selectedOptions) {},
              options: <ValueItem>[
                ValueItem(label: 'Dropdown_$i Option 1', value: '1'),
                ValueItem(label: 'Dropdown_$i Option 2', value: '2'),
                ValueItem(label: 'Dropdown_$i Option 3', value: '3'),
                ValueItem(label: 'Dropdown_$i Option 4', value: '4'),
                ValueItem(label: 'Dropdown_$i Option 5', value: '5'),
                ValueItem(label: 'Dropdown_$i Option 6', value: '6'),
              ],
              selectionType: SelectionType.single,
              chipConfig: const ChipConfig(wrapType: WrapType.wrap),
              dropdownHeight: 300,
              optionTextStyle: const TextStyle(fontSize: 16),
              selectedOptionIcon: const Icon(Icons.check_circle),
            )

And in multiselect_dropdown.dart I have added a print statement in function _handleFocusChange and _buildOverlayEntry to log when it has focus and when an overlay is built

void _handleFocusChange() {

     print('focus changed: ${_focusNode.hasFocus}  ${widget.options[0]}');

   ... rest of code
}

OverlayEntry _buildOverlayEntry() {
    print('overlay built:   ${widget.options[0]}');
    ... rest of code
}

Now trying Case 2 when user clicks on textfield and then pressed tab to navigate, the output logs are

flutter: focus changed: true ValueItem(label: Dropdown_0 Option 1, value: 1) flutter: overlay built: ValueItem(label: Dropdown_0 Option 1, value: 1) flutter: focus changed: true ValueItem(label: Dropdown_1 Option 1, value: 1) flutter: overlay built: ValueItem(label: Dropdown_1 Option 1, value: 1) flutter: focus changed: false ValueItem(label: Dropdown_0 Option 1, value: 1) flutter: focus changed: true ValueItem(label: Dropdown_2 Option 1, value: 1) flutter: overlay built: ValueItem(label: Dropdown_2 Option 1, value: 1) flutter: focus changed: false ValueItem(label: Dropdown_1 Option 1, value: 1) flutter: focus changed: true ValueItem(label: Dropdown_3 Option 1, value: 1) flutter: overlay built: ValueItem(label: Dropdown_3 Option 1, value: 1) flutter: focus changed: false ValueItem(label: Dropdown_2 Option 1, value: 1) flutter: focus changed: true ValueItem(label: Dropdown_4 Option 1, value: 1) flutter: overlay built: ValueItem(label: Dropdown_4 Option 1, value: 1) flutter: focus changed: false ValueItem(label: Dropdown_3 Option 1, value: 1) flutter: focus changed: false ValueItem(label: Dropdown_4 Option 1, value: 1)

Focus is working as it should

Now, CASE 3, when user clicks on the first dropdown and then tries to navigate with tab key the output logs are

flutter: focus changed: true ValueItem(label: Dropdown_0 Option 1, value: 1) flutter: overlay built: ValueItem(label: Dropdown_0 Option 1, value: 1) flutter: focus changed: true ValueItem(label: Dropdown_0 Option 1, value: 1) flutter: overlay built: ValueItem(label: Dropdown_0 Option 1, value: 1) flutter: focus changed: true ValueItem(label: Dropdown_1 Option 1, value: 1) flutter: overlay built: ValueItem(label: Dropdown_1 Option 1, value: 1) flutter: focus changed: false ValueItem(label: Dropdown_0 Option 1, value: 1) flutter: focus changed: true ValueItem(label: Dropdown_2 Option 1, value: 1) flutter: overlay built: ValueItem(label: Dropdown_2 Option 1, value: 1) flutter: focus changed: false ValueItem(label: Dropdown_1 Option 1, value: 1) flutter: focus changed: true ValueItem(label: Dropdown_3 Option 1, value: 1) flutter: overlay built: ValueItem(label: Dropdown_3 Option 1, value: 1) flutter: focus changed: false ValueItem(label: Dropdown_2 Option 1, value: 1) flutter: focus changed: true ValueItem(label: Dropdown_4 Option 1, value: 1) flutter: overlay built: ValueItem(label: Dropdown_4 Option 1, value: 1) flutter: focus changed: false ValueItem(label: Dropdown_3 Option 1, value: 1) flutter: focus changed: false ValueItem(label: Dropdown_4 Option 1, value: 1)

In the logs we can clearly see overlay for dropdown 0 is built two times when user clicks on it second time when user presses tab key , when user pressed tab key for the second time next dropdown is triggered

kartikey321 commented 7 months ago

The main issue here is when user clicks on the dropdown the _focusNode is foccussed, but when the user presses tab key another focusNode which has the parent focusNode as the original focusNode _focusNode that is used for the dropdown widget.

To solve this issue we can restrict focus to go inside of the _focuNode or something else

oi-narendra commented 4 months ago

Check if the problem exists in the latest version. v3.0.0