如何在Flutter中点击其他窗口小部件时打开DropdownButton? [英] How to open DropdownButton when other widget is tapped, in Flutter?
问题描述
我需要有一个 DropdownButton
的选项列表,当点按其他小部件时,可以以编程方式打开/显示。我知道这可能不是UI最佳实践,但我需要这种行为:
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 all, but I need this behavior:
例如,在下面的结构中,我可能需要点击 Text( every)
打开相邻的 DropdownButton
的下拉列表,其行为类似于单击一个< select>
的HTML标签。
As an example, in a structure like the one below, I may need to have taping Text("every")
to open the neighboring DropdownButton
's dropdown list, behaviors similar to clicking a <select>
's label in HTML.
Row(children: [
Padding(
padding: const EdgeInsets.only(right: 16),
child: Text('every'),
),
Expanded(
child: DropdownButton<String>(
value: _data['every'],
onChanged: (String val) => setState(() => _data['every'] = val),
items: _every_options.map<DropdownMenuItem<String>>(
(String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
},
).toList(),
isExpanded: true,
),
),
]);
注意:尽管我需要一般解决方案这个问题,而不仅仅是如何使文本
在下面的树中表现得有点像 HTML标签。
NOTE: I am in need though of the general solution to this problem, not just how to make that Text
behave somewhat "like a HTML label" in the tree below. It may need to be triggered to open by maybe a further away button etc.
推荐答案
这是(许多)设计的API限制中的一个...
It's one (of many) designed API limitations...
最简单的方法,无需修改SDK,即可完成所需的操作,复制 dropdown.dart 并创建自己的版本假设它是 custom_dropdown.dart ,然后在其中粘贴代码...
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 ...
在第546行中,将该类重命名为 CustomDropdownButton ,然后在660和663行中将_DropdownButtonState重命名为 CustomDropdownButtonState ,(我们需要将状态类公开到文件外部)。
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 ).
现在,您可以使用
进行任何操作,尽管您对_handleTap()感兴趣,可以打开覆盖菜单选项。
Now you can do whatever you want with it, although you were interested in the _handleTap(), to open the overlay menu options.
公开_handleTap(),并重构代码,添加另一种方法,例如:
Instead of making _handleTap() public, and refactor the code, add another method like:
(line 726)
void callTap() => _handleTap();
现在,更改代码以使用DropdownButton代替Flutter的DropdownButton,关键是设置键(全局键):P
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<String, String> _data;
List<String> _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<String>(
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();
});
}
这篇关于如何在Flutter中点击其他窗口小部件时打开DropdownButton?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!