AhmedLSayed9 / dropdown_button2

Flutter's core Dropdown Button widget with steady dropdown menu and many other features.
https://pub.dev/packages/dropdown_button2
MIT License
264 stars 122 forks source link

Disable focus on DropdownItem #293

Open npateras opened 3 months ago

npateras commented 3 months ago

I have a dropdown item that has a focus widget, however, there seems to be an internal focus which makes my dropdown items have 2 focuses on the same item, and I couldn't find a way to disable the internal one.

yashanghan22 commented 2 months ago

@npateras Can you please explain more or share your code so I can understand?

To disable the onTap method for a dropdown item, set the dropdownItem parameter to enable: false. This will prevent onTap from working for that specific item.

npateras commented 2 months ago

@npateras Can you please explain more or share your code so I can understand?

To disable the onTap method for a dropdown item, set the dropdownItem parameter to enable: false. This will prevent onTap from working for that specific item.

Thanks for your reply. Let me explain what I meant, I want the dropdown item to work so setting enable to false doesn't fix my issue, I have a case where I added a Focus widget to my item widget so I can change a variable when the item is focused. However, by adding a focus widget it makes my items need 2x keyboard presses to move to the next item, like it has 2x Focus widgets! So I need to a way to handle that through DropdownItem. Perhaps expose a onFocusChange method similarly to the onTap method of DropdownItem?

yashanghan22 commented 2 months ago

Could you please provide some additional details to help address your issue?

  1. Focus Widget Details: Which Focus widget are you using in the dropdown item?
  2. Desired Focus Change Action: What specific action do you want to execute when the focus changes?
  3. Platform Information: On which platform are you encountering this issue?
  4. Hover Functionality: Have you tested the widget with items that contain onHover functionality?

Additionally, it would be helpful if you could share a snippet of the code where you are experiencing this issue.

npateras commented 1 month ago

Could you please provide some additional details to help address your issue?

  1. Focus Widget Details: Which Focus widget are you using in the dropdown item?
  2. Desired Focus Change Action: What specific action do you want to execute when the focus changes?
  3. Platform Information: On which platform are you encountering this issue?
  4. Hover Functionality: Have you tested the widget with items that contain onHover functionality?

Additionally, it would be helpful if you could share a snippet of the code where you are experiencing this issue.

Hello and sorry for the slow reply, here are the details you need.

  1. I am using the Focus widget.
  2. I am using a focus because I want to change the border of my dropdown when focused, however the problem is that it creates 2x Focuses.
  3. Web
  4. Not really, but I think this wouldn't fix my issue.

The code sample below demonstrates the problem exactly, this exact same issue would also happen in the dropdown menu items giving us double focus before switching to the next entry which do different things.

class HomeScreen extends StatefulWidget {
  /// Constructs a [HomeScreen]
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {final List<String> items = [
  'Item1',
  'Item2',
  'Item3',
  'Item4',
  'Item5',
  'Item6',
  'Item7',
  'Item8',
];

final ValueNotifier<String?> valueListenable = ValueNotifier<String?>(null);
final FocusNode _focusNode = FocusNode();

@override
void initState() {
  super.initState();
  _focusNode.addListener(() {
    setState(() {});
  });
}

@override
void dispose() {
  _focusNode.dispose();
  super.dispose();
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: const Text('Home Screen')),
    body: SingleChildScrollView(
      child: Column(
        children: [
          Center(
            child: DropdownButtonHideUnderline(
              child: Focus(
                focusNode: _focusNode,
                child: DropdownButton2<String>(
                  isExpanded: true,
                  hint: Text(
                    'Select Item',
                    style: TextStyle(
                      fontSize: 14,
                      color: Theme.of(context).hintColor,
                    ),
                  ),
                  items: items
                      .map((String item) => DropdownItem<String>(
                    value: item,
                    height: 40,
                    child: Text(
                      item,
                      style: const TextStyle(
                        fontSize: 14,
                      ),
                    ),
                  ))
                      .toList(),
                  valueListenable: valueListenable,
                  onChanged: (String? value) {
                    valueListenable.value = value;
                  },
                  buttonStyleData: ButtonStyleData(
                    padding: const EdgeInsets.symmetric(horizontal: 16),
                    height: 40,
                    width: 140,
                    decoration: BoxDecoration(
                      borderRadius: const BorderRadius.all(Radius.circular(14)),
                      border: Border.all(
                          color: Colors.black45,
                          width: _focusNode.hasFocus ? 2 : 1,
                        ),
                      ),
                    ),
                  ),
                ),
              ),
          ),
        ],
      ),
    ),
  );
}
}

I have attached two videos that explain this behaviour:

Without having double focus effect on the dropdown: https://github.com/user-attachments/assets/dd6629c3-ea93-4582-a1b6-89b93710f05d

While having double focus effect on the dropdown: https://github.com/user-attachments/assets/6d5f7681-a245-4cc1-8ae0-353e5c00aa05

yashanghan22 commented 1 month ago

Sorry for the late reply.

Don't use Focus or FocusNode to check if a dropdown is focused. There are simpler ways to do this.

1. Using InkWell and GestureDetector

2. Using MouseRegion

MousrRegion Docs: https://api.flutter.dev/flutter/widgets/MouseRegion-class.html

npateras commented 1 month ago

Sorry for the late reply.

Don't use Focus or FocusNode to check if a dropdown is focused. There are simpler ways to do this.

1. Using InkWell and GestureDetector

  • To change the border when hovering over a dropdown button, wrap the dropdown with InkWell or GestureDetector. These provide an onHover callback that tells you if the widget is being hovered over. You can use this boolean value to change the border color of the dropdown.

2. Using MouseRegion

  • Another solution is to use MouseRegion, which is provided by Flutter. It detects mouse cursor activity, allowing you to get hover activity by wrapping it around the dropdown.

MousrRegion Docs: https://api.flutter.dev/flutter/widgets/MouseRegion-class.html

But this is about the focused functionality using keyboard, it has nothing to do with hover and mouse, I already tried inkwell and it does not fix my problem.

yashanghan22 commented 1 month ago

No @npateras, Mouse Region is only for Mouse activity on the screen have you tried MouseRegion????

npateras commented 1 month ago

No @npateras, Mouse Region is only for Mouse activity on the screen have you tried MouseRegion????

Again, this has nothing to do with mouse activity...

yashanghan22 commented 1 month ago

so how you want to focus that widget by keyboard?

i means by pressing tab button or enter button?

npateras commented 1 month ago

so how you want to focus that widget by keyboard?

i means by pressing tab button or enter button?

Exactly, I am using DropdownButton2 for Web which means handling focusing is one of the cases I am handling. When I say focusing I am not referring to the focus of the mouse, but the focus of the keyboard with the tab key, did you see the recording videos I shared?

yashanghan22 commented 1 month ago

@npateras sorry for misunderstanding i got your point right now.

so in this code you are showing border as per hasFocus value so are you getting this value true or false from the focusNode???