How to open DropdownButton when other widget is tapped, in Flutter?

后端 未结 2 782
抹茶落季
抹茶落季 2020-12-17 21:51

I need to have a DropdownButton\'s list of options open/show programmatically when some other widget is tapped. I know that this may not be UI-best-practice and

2条回答
  •  抹茶落季
    2020-12-17 22:18

    It's one (of many) designed API limitations...

    The easiest approach to accomplish what you want, without modifying the SDK, copy dropdown.dart, and create your own version of it, let's say custom_dropdown.dart, and paste the code there ...

    in line 546, rename the class to CustomDropdownButton, and in line 660 and 663 rename _DropdownButtonState to CustomDropdownButtonState, ( we need the state class to be exposed outside the file ).

    Now you can do whatever you want with it, although you were interested in the _handleTap(), to open the overlay menu options.

    Instead of making _handleTap() public, and refactor the code, add another method like:

    (line 726)
    void callTap() => _handleTap();
    

    Now, change your code to use your DropdownButton instead of the Flutter's DropdownButton, the key is to "set the key" (Global one) :P

    // some stateful widget implementation.

      Map _data;
      List _every_options;
      // we need the globalKey to access the State.
      final GlobalKey dropdownKey = GlobalKey();
    
      @override
      void initState() {
        _every_options = List.generate(10, (i) => "item $i");
        _data = {'every': _every_options.first};
        simulateClick();
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return SafeArea(
          child: Row(children: [
            Padding(
              padding: const EdgeInsets.only(right: 16),
              child: Text('every'),
            ),
            Expanded(
              child: CustomDropdownButton(
                key: dropdownKey,
                value: _data['every'],
                onChanged: (String val) => setState(() => _data['every'] = val),
                items: _every_options
                    .map((str) => DropdownMenuItem(
                          value: str,
                          child: Text(str),
                        ))
                    .toList(),
                isExpanded: true,
              ),
            ),
          ]),
        );
      }
    
      void simulateClick() {
        Timer(Duration(seconds: 2), () {
          // here's the "magic" to retrieve the state... not very elegant, but works.
          CustomDropdownButtonState state = dropdownKey.currentState;
          state.callTap();
        });
      }
    

提交回复
热议问题