Flutter - 在 BottomNavigationBar 中显示一个 PopupMenuButton
Flutter - showing a PopupMenuButton in BottomNavigationBar
我试图在单击导航栏项目时显示菜单。这是我的尝试:
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: MyAppBar(
title: "Home",
context: context,
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(
icon: new Icon(Icons.book), title: Text('Second')),
BottomNavigationBarItem(
icon: new PopupMenuButton(
icon: Icon(Icons.add),
itemBuilder: (_) => <PopupMenuItem<String>>[
new PopupMenuItem<String>(
child: const Text('test1'), value: 'test1'),
new PopupMenuItem<String>(
child: const Text('test2'), value: 'test2'),
],
),
title: Text('more')),
],
currentIndex: 0,
),
body: new Container()));
}
我遇到了两个问题。第一个是 NavigationBarItem 的显示。 icon
和 title
之间有一个填充,我无法删除(即使添加 padding: EdgeInsets.all(0.0)
)(如下图所示)。第二个是我需要准确单击图标才能显示菜单。
我尝试在单击 index=2
的 BottomNavigationBarItem
(例如)时直接调用 showMenu
(PopupMenuButton
调用的方法)。但是如何确定菜单应该出现的起源位置是很棘手的。
这是我的尝试:
@override
Widget build(BuildContext context) {
return Material(
child: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text("Home"),
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(
icon: new Icon(Icons.book), title: Text('Second')),
BottomNavigationBarItem(
icon: new Icon(Icons.add),
title: Text('More')),
],
currentIndex: 0,
onTap: (int index) async {
if(index == 2){
await showMenu<String>(
context: context,
position: RelativeRect.fromLTRB(1000.0, 1000.0, 0.0, 0.0),
items: <PopupMenuItem<String>>[
new PopupMenuItem<String>(
child: const Text('test1'), value: 'test1'),
new PopupMenuItem<String>(
child: const Text('test2'), value: 'test2'),
],
elevation: 8.0,
);
}
},
),
body: new Container())));
}
基本上使用您所说的 showMenu
方法,除了我将 RelativeRect 的值设置为 1000.0 以便它位于任何设备的右下角。您可以乱用这些值来获得更靠近图标上方的位置,但我认为这样设置效果很好:
这里尝试直接使用 showMenu
并调用函数 buttonMenuPosition
来获取菜单的位置。它相当脆弱,但您可以将按钮的位置更改为中间,例如使用 bar.size.center
而不是 bar.size.bottomRight
。使用一些 MATH 并通过手动操作 Offset
对象(if/when 你有超过 3 个项目),你可以更改位置以将菜单放在一个不是'不是中心或末尾)。
RelativeRect buttonMenuPosition(BuildContext c) {
final RenderBox bar = c.findRenderObject();
final RenderBox overlay = Overlay.of(c).context.findRenderObject();
final RelativeRect position = RelativeRect.fromRect(
Rect.fromPoints(
bar.localToGlobal(bar.size.bottomRight(Offset.zero), ancestor: overlay),
bar.localToGlobal(bar.size.bottomRight(Offset.zero), ancestor: overlay),
),
Offset.zero & overlay.size,
);
return position;
}
@override
Widget build(BuildContext context) {
final key = GlobalKey<State<BottomNavigationBar>>();
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text("Home"),
),
bottomNavigationBar: BottomNavigationBar(
key: key,
items: [
const BottomNavigationBarItem(
icon: Icon(Icons.home), title: Text('Home')),
const BottomNavigationBarItem(
icon: Icon(Icons.book), title: Text('Second')),
const BottomNavigationBarItem(
icon: Icon(Icons.add), title: Text('more')),
],
currentIndex: 0,
onTap: (index) async {
final position = buttonMenuPosition(key.currentContext);
if (index == 2) {
final result = await showMenu(
context: context,
position: position,
items: <PopupMenuItem<String>>[
const PopupMenuItem<String>(
child: Text('test1'), value: 'test1'),
const PopupMenuItem<String>(
child: Text('test2'), value: 'test2'),
],
);
}
},
),
body: Container()));
}
我试图在单击导航栏项目时显示菜单。这是我的尝试:
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: MyAppBar(
title: "Home",
context: context,
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(
icon: new Icon(Icons.book), title: Text('Second')),
BottomNavigationBarItem(
icon: new PopupMenuButton(
icon: Icon(Icons.add),
itemBuilder: (_) => <PopupMenuItem<String>>[
new PopupMenuItem<String>(
child: const Text('test1'), value: 'test1'),
new PopupMenuItem<String>(
child: const Text('test2'), value: 'test2'),
],
),
title: Text('more')),
],
currentIndex: 0,
),
body: new Container()));
}
我遇到了两个问题。第一个是 NavigationBarItem 的显示。 icon
和 title
之间有一个填充,我无法删除(即使添加 padding: EdgeInsets.all(0.0)
)(如下图所示)。第二个是我需要准确单击图标才能显示菜单。
我尝试在单击 index=2
的 BottomNavigationBarItem
(例如)时直接调用 showMenu
(PopupMenuButton
调用的方法)。但是如何确定菜单应该出现的起源位置是很棘手的。
这是我的尝试:
@override
Widget build(BuildContext context) {
return Material(
child: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text("Home"),
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(
icon: new Icon(Icons.book), title: Text('Second')),
BottomNavigationBarItem(
icon: new Icon(Icons.add),
title: Text('More')),
],
currentIndex: 0,
onTap: (int index) async {
if(index == 2){
await showMenu<String>(
context: context,
position: RelativeRect.fromLTRB(1000.0, 1000.0, 0.0, 0.0),
items: <PopupMenuItem<String>>[
new PopupMenuItem<String>(
child: const Text('test1'), value: 'test1'),
new PopupMenuItem<String>(
child: const Text('test2'), value: 'test2'),
],
elevation: 8.0,
);
}
},
),
body: new Container())));
}
基本上使用您所说的 showMenu
方法,除了我将 RelativeRect 的值设置为 1000.0 以便它位于任何设备的右下角。您可以乱用这些值来获得更靠近图标上方的位置,但我认为这样设置效果很好:
这里尝试直接使用 showMenu
并调用函数 buttonMenuPosition
来获取菜单的位置。它相当脆弱,但您可以将按钮的位置更改为中间,例如使用 bar.size.center
而不是 bar.size.bottomRight
。使用一些 MATH 并通过手动操作 Offset
对象(if/when 你有超过 3 个项目),你可以更改位置以将菜单放在一个不是'不是中心或末尾)。
RelativeRect buttonMenuPosition(BuildContext c) {
final RenderBox bar = c.findRenderObject();
final RenderBox overlay = Overlay.of(c).context.findRenderObject();
final RelativeRect position = RelativeRect.fromRect(
Rect.fromPoints(
bar.localToGlobal(bar.size.bottomRight(Offset.zero), ancestor: overlay),
bar.localToGlobal(bar.size.bottomRight(Offset.zero), ancestor: overlay),
),
Offset.zero & overlay.size,
);
return position;
}
@override
Widget build(BuildContext context) {
final key = GlobalKey<State<BottomNavigationBar>>();
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text("Home"),
),
bottomNavigationBar: BottomNavigationBar(
key: key,
items: [
const BottomNavigationBarItem(
icon: Icon(Icons.home), title: Text('Home')),
const BottomNavigationBarItem(
icon: Icon(Icons.book), title: Text('Second')),
const BottomNavigationBarItem(
icon: Icon(Icons.add), title: Text('more')),
],
currentIndex: 0,
onTap: (index) async {
final position = buttonMenuPosition(key.currentContext);
if (index == 2) {
final result = await showMenu(
context: context,
position: position,
items: <PopupMenuItem<String>>[
const PopupMenuItem<String>(
child: Text('test1'), value: 'test1'),
const PopupMenuItem<String>(
child: Text('test2'), value: 'test2'),
],
);
}
},
),
body: Container()));
}