我正在通过Flutter Gallery查看与CupertinoPicker相关的代码。
以下是相关代码摘录:
child: new GestureDetector(
// Blocks taps from propagating to the modal sheet and popping.
// onTap: () { },
child: new SafeArea(
child: new CupertinoPicker(
scrollController: scrollController,
itemExtent: _kPickerItemHeight,
backgroundColor: CupertinoColors.white,
onSelectedItemChanged: (int index) {
setState(() {
print(_selectedItemIndex);
_selectedItemIndex = index;
});
},
children: new List<Widget>.generate(coolColorNames.length, (int index) {
return new Center(child:
new Text(coolColorNames[index]),
);
}),
),
),
),
现在,当CupertinoPicker关闭时,我需要一个回调/监听器,换句话说,当用户做出选择并且他的选择是最终的时,我需要知道他的最终选择是什么。
这里的用例是我想在底片关闭时根据他的最终选择进行api回调。
目前,由于只有onSelectedItemChanged的回调,我只能获取用户旋转选择器的值。见下面的gif。
我看到BottomSheet小部件有一个onClosing回调:https://docs.flutter.io/flutter/material/BottomSheet-class.html
但是我很困惑如何获得它的实例,因为Flutter Gallery样本使用以下代码调用底层,并且没有方法从代码中获取底层:
new GestureDetector(
onTap: () async {
await showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return _buildBottomPicker();
},
);
},
child: _buildMenu(),
),
有谁知道如何获得回调侦听器?
编辑 - 基于Remi的解决方案,我在onTap回调中添加了Navigator.of(context).pop(value)代码。但是,CupertinoPicker不是持久的,因此如果用户触摸选择器外部,选择器会自行解除并返回空值:
Widget _buildBottomPicker() {
final FixedExtentScrollController scrollController =
new FixedExtentScrollController(initialItem: _selectedItemIndex);
return new Container(
height: _kPickerSheetHeight,
color: CupertinoColors.white,
child: new DefaultTextStyle(
style: const TextStyle(
color: CupertinoColors.black,
fontSize: 22.0,
),
child: new GestureDetector(
// Blocks taps from propagating to the modal sheet and popping.
onTap: () { Navigator.of(context).pop(_selectedItemIndex);},
child: new SafeArea(
child: new CupertinoPicker(
scrollController: scrollController,
itemExtent: _kPickerItemHeight,
backgroundColor: CupertinoColors.white,
onSelectedItemChanged: (int index) {
setState(() {
// print(_selectedItemIndex);
// Navigator.of(context).pop(index);
_selectedItemIndex = index;
});
},
children: new List<Widget>.generate(coolColorNames.length, (int index) {
return new Center(child:
new Text(coolColorNames[index]),
);
}),
),
),
),
),
);
}
答案 0 :(得分:7)
它实际上比你想象的要简单得多。
showDialog
及其对应方(包括showModalBottomSheet
)会返回包含结果的Future
。所以你可以做到以下几点:
final selectedId = await showModalBottomSheet<int>(...);
唯一的要求是,当弹出你的模态/对话框/路线/其他时,你会Navigator.of(context).pop(value)
发送该值。
答案 1 :(得分:0)
就像前面的回答一样,所需的值以Future的形式返回给您。虽然这是事实,但对我而言,如何实现它并不明显。就我而言,我想按同一屏幕上的类别列表过滤待办事项列表。因此,通过使用onSelectedItemChanged返回的int键,我可以像这样进行过滤...
{
"text": "New comic book alert!",
"attachments": [
{
"title": "The Further Adventures of Slackbot",
"fields": [
{
"title": "Volume",
"value": "1",
"short": true
},
{
"title": "Issue",
"value": "3",
"short": true
}
],
"author_name": "Stanford S. Strickland",
"author_icon": "http://a.slack-edge.com/7f18https://a.slack-edge.com/a8304/img/api/homepage_custom_integrations-2x.png",
"image_url": "http://i.imgur.com/OJkaVOI.jpg?1"
},
{
"title": "Synopsis",
"text": "After @episod pushed exciting changes to a devious new branch back in Issue 1, Slackbot notifies @don about an unexpected deploy..."
},
{
"fallback": "Would you recommend it to customers?",
"title": "Would you recommend it to customers?",
"callback_id": "comic_1234_xyz",
"color": "#3AA3E3",
"attachment_type": "default",
"actions": [
{
"name": "recommend",
"text": "Recommend",
"type": "button",
"value": "recommend"
},
{
"name": "no",
"text": "No",
"type": "button",
"value": "bad"
}
]
}
]
}
您无需在showCupertinoModalPopup或类似的内容上设置决赛...
Widget _buildCategoryPicker(BuildContext context, _todoBloc) {
final FixedExtentScrollController scrollController =
FixedExtentScrollController(initialItem: _selectedIndex);
return GestureDetector(
onTap: () async {
await showCupertinoModalPopup<String>(
context: context,
builder: (BuildContext context) {
return _buildBottomPicker(
CupertinoPicker(
(...)
onSelectedItemChanged: (int index) {
setState(() => _selectedIndex = index);
},
children: (...),
), // CupertinoPicker
);
},
); // await showCupertinoModalPopup
// Filters the todoList.
_todoBloc.filter.add(categories[_selectedIndex]);
},
child: _buildMenu(
...
),
);
}
答案 2 :(得分:0)
像这样:
future.whenComplete(() => requestRefresh());
答案 3 :(得分:0)
showModalBottomSheet(
context: context,
builder: (_) {
return GestureDetector(
onTap: () => Navigator.of(context).pop(), // closing showModalBottomSheet
child: FlutterLogo(size: 200),
);
},
);