Flutter AppBar 弹出菜单按钮。想要带有 Pop 的前导图标和带有 Popup 的右侧图标
Flutter AppBar PopupMenuButton. Want leading Icon with Pop and right-side Icon with Popup
--> Screenshot Image <-- 在通过教程和其他资源学习数周后,将 Flutter 用于第一个项目。使用带前导图标的 AppBar(左)和带图标的 PopupMenuButton(右)。弹出菜单工作正常,但希望在 left/leading 图标上有一个弹出菜单。
我试过在右侧的操作小部件下复制代码,但 Flutter 不喜欢它。我相信领先的图标是有限的,而 icon/right-side 可以处理更多 widgets/code.
import 'package:flutter/material.dart';
import 'package:paycheck_academy/fab_bottom_app_bar.dart';
import 'package:paycheck_academy/fab_with_icons.dart';
import 'package:paycheck_academy/layout.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or press Run > Flutter Hot Reload in IntelliJ). Notice that the
// counter didn't reset back to zero; the application is not restarted.
primarySwatch: Colors.blueGrey,
),
home: new MyHomePage(title: 'Paycheck Academy'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
String _lastSelected = 'TAB: 0';
void _selectedTab(int index) {
setState(() {
_lastSelected = 'TAB: $index';
});
}
void _selectedFab(int index) {
setState(() {
_lastSelected = 'FAB: $index';
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
//Can add leading icon/function if needed
leading: Builder(
builder: (BuildContext context) {
return IconButton(
icon: Icon(Icons.menu),
onPressed: () {},
);
},
),
/* Icon(
Icons.exit_to_app,
),*/
actions: <Widget>[
PopupMenuButton(
icon: Icon(Icons.account_box),
tooltip: 'Account',
itemBuilder: (context) => [
PopupMenuItem(
child: Text(
'Profile',
style: TextStyle(
color: Colors.blueGrey,
),
),
),
PopupMenuItem(
child: Text(
'FAQ',
style: TextStyle(
color: Colors.blueGrey,
),
),
),
PopupMenuItem(
child: Text(
'Website',
style: TextStyle(
color: Colors.blueGrey,
),
),
),
PopupMenuItem(
child: Text(
'Logout',
style: TextStyle(
color: Colors.blueGrey,
),
),
),
],
),
],
title: Text(widget.title),
textTheme: TextTheme(
title: TextStyle(
color: Colors.white,
fontSize: 22.0,
),
),
/*actions: <Widget>[
IconButton(
icon: Icon(
Icons.account_box,
color: Colors.white,
),
onPressed: () {},
),
],*/
),
body: Center(
child: Text(
_lastSelected,
style: TextStyle(fontSize: 32.0),
),
),
bottomNavigationBar: FABBottomAppBar(
centerItemText: '',
backgroundColor: Colors.blueGrey,
color: Colors.white,
selectedColor: Colors.yellowAccent,
notchedShape: CircularNotchedRectangle(),
onTabSelected: _selectedTab,
items: [
FABBottomAppBarItem(
iconData: Icons.school,
text: 'Academy',
),
FABBottomAppBarItem(
iconData: Icons.insert_chart,
text: 'Reports',
),
FABBottomAppBarItem(
iconData: Icons.attach_money,
text: 'Income',
),
FABBottomAppBarItem(
iconData: Icons.local_grocery_store,
text: 'Expense',
),
],
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: _buildFab(
context), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Widget _buildFab(BuildContext context) {
final icons = [
Icons.attach_money,
Icons.local_grocery_store,
];
return AnchoredOverlay(
showOverlay: true,
overlayBuilder: (context, offset) {
return CenterAbout(
position: Offset(offset.dx, offset.dy - icons.length * 35.0),
child: FabWithIcons(
icons: icons,
onIconTapped: _selectedFab,
),
);
},
child: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
elevation: 2.0,
),
);
}
}
所以...我试过了。而且看起来就是你想要的。
class CustomAppBar extends StatefulWidget implements PreferredSizeWidget{
final double height;
CustomAppBar({Key key,this.height}):super(key:key);
Size get preferredSize => Size.fromHeight(height);
@override
_CustomAppBarState createState() => _CustomAppBarState();
}
class _CustomAppBarState extends State<CustomAppBar> {
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
color: Colors.grey[300],
child: Padding(
padding: EdgeInsets.all(0),
child: Container(
color: Colors.red,
padding: EdgeInsets.fromLTRB(5, 30, 5, 5),
child: Row(children: [
PopupMenuButton(
icon: Icon(Icons.view_list,color:Colors.white),
itemBuilder: (context) => [
PopupMenuItem(
child: Text("Is this"),
),
PopupMenuItem(
child: Text("What"),
),
PopupMenuItem(
child: Text("You Want?"),
),
],
),
Expanded(
child: Container(
color: Colors.transparent,
child: Text("Hello",
style: TextStyle(
fontSize:20.0,
color:Colors.white,
),),
),
),
]),
),
),
),
],
);
}
}
并且您可以使用此 Class 替换 AppBar()..
即:appBar: CustomAppBar(height:95.0),
This is how it look
And this is the pop up
顺便说一句..我也是 flutter 的新手...所以我的代码可能有点愚蠢...
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('PopupMenuButton (Stateless)'),
actions: <Widget>[
PopupMenuButton(
onSelected: (value) {
//print the selected option
print(value);
//Update the current choice.
//However, this choice won't be updated in body section since it's a Stateless widget.
choice = value.toString();
},
itemBuilder: (BuildContext context) {
return NavLinks.values.map((link) {
return PopupMenuItem(
value: link,
child: Text(displayString(link)),
);
}).toList();
},
),
],
),
body: Center(
child: Text(
//Print the current choice
choice,
style: TextStyle(fontSize: 30),
),
),
);
}
--> Screenshot Image <-- 在通过教程和其他资源学习数周后,将 Flutter 用于第一个项目。使用带前导图标的 AppBar(左)和带图标的 PopupMenuButton(右)。弹出菜单工作正常,但希望在 left/leading 图标上有一个弹出菜单。
我试过在右侧的操作小部件下复制代码,但 Flutter 不喜欢它。我相信领先的图标是有限的,而 icon/right-side 可以处理更多 widgets/code.
import 'package:flutter/material.dart';
import 'package:paycheck_academy/fab_bottom_app_bar.dart';
import 'package:paycheck_academy/fab_with_icons.dart';
import 'package:paycheck_academy/layout.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or press Run > Flutter Hot Reload in IntelliJ). Notice that the
// counter didn't reset back to zero; the application is not restarted.
primarySwatch: Colors.blueGrey,
),
home: new MyHomePage(title: 'Paycheck Academy'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
String _lastSelected = 'TAB: 0';
void _selectedTab(int index) {
setState(() {
_lastSelected = 'TAB: $index';
});
}
void _selectedFab(int index) {
setState(() {
_lastSelected = 'FAB: $index';
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
//Can add leading icon/function if needed
leading: Builder(
builder: (BuildContext context) {
return IconButton(
icon: Icon(Icons.menu),
onPressed: () {},
);
},
),
/* Icon(
Icons.exit_to_app,
),*/
actions: <Widget>[
PopupMenuButton(
icon: Icon(Icons.account_box),
tooltip: 'Account',
itemBuilder: (context) => [
PopupMenuItem(
child: Text(
'Profile',
style: TextStyle(
color: Colors.blueGrey,
),
),
),
PopupMenuItem(
child: Text(
'FAQ',
style: TextStyle(
color: Colors.blueGrey,
),
),
),
PopupMenuItem(
child: Text(
'Website',
style: TextStyle(
color: Colors.blueGrey,
),
),
),
PopupMenuItem(
child: Text(
'Logout',
style: TextStyle(
color: Colors.blueGrey,
),
),
),
],
),
],
title: Text(widget.title),
textTheme: TextTheme(
title: TextStyle(
color: Colors.white,
fontSize: 22.0,
),
),
/*actions: <Widget>[
IconButton(
icon: Icon(
Icons.account_box,
color: Colors.white,
),
onPressed: () {},
),
],*/
),
body: Center(
child: Text(
_lastSelected,
style: TextStyle(fontSize: 32.0),
),
),
bottomNavigationBar: FABBottomAppBar(
centerItemText: '',
backgroundColor: Colors.blueGrey,
color: Colors.white,
selectedColor: Colors.yellowAccent,
notchedShape: CircularNotchedRectangle(),
onTabSelected: _selectedTab,
items: [
FABBottomAppBarItem(
iconData: Icons.school,
text: 'Academy',
),
FABBottomAppBarItem(
iconData: Icons.insert_chart,
text: 'Reports',
),
FABBottomAppBarItem(
iconData: Icons.attach_money,
text: 'Income',
),
FABBottomAppBarItem(
iconData: Icons.local_grocery_store,
text: 'Expense',
),
],
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: _buildFab(
context), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Widget _buildFab(BuildContext context) {
final icons = [
Icons.attach_money,
Icons.local_grocery_store,
];
return AnchoredOverlay(
showOverlay: true,
overlayBuilder: (context, offset) {
return CenterAbout(
position: Offset(offset.dx, offset.dy - icons.length * 35.0),
child: FabWithIcons(
icons: icons,
onIconTapped: _selectedFab,
),
);
},
child: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
elevation: 2.0,
),
);
}
}
所以...我试过了。而且看起来就是你想要的。
class CustomAppBar extends StatefulWidget implements PreferredSizeWidget{
final double height;
CustomAppBar({Key key,this.height}):super(key:key);
Size get preferredSize => Size.fromHeight(height);
@override
_CustomAppBarState createState() => _CustomAppBarState();
}
class _CustomAppBarState extends State<CustomAppBar> {
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
color: Colors.grey[300],
child: Padding(
padding: EdgeInsets.all(0),
child: Container(
color: Colors.red,
padding: EdgeInsets.fromLTRB(5, 30, 5, 5),
child: Row(children: [
PopupMenuButton(
icon: Icon(Icons.view_list,color:Colors.white),
itemBuilder: (context) => [
PopupMenuItem(
child: Text("Is this"),
),
PopupMenuItem(
child: Text("What"),
),
PopupMenuItem(
child: Text("You Want?"),
),
],
),
Expanded(
child: Container(
color: Colors.transparent,
child: Text("Hello",
style: TextStyle(
fontSize:20.0,
color:Colors.white,
),),
),
),
]),
),
),
),
],
);
}
}
并且您可以使用此 Class 替换 AppBar()..
即:appBar: CustomAppBar(height:95.0),
This is how it look
And this is the pop up
顺便说一句..我也是 flutter 的新手...所以我的代码可能有点愚蠢...
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('PopupMenuButton (Stateless)'),
actions: <Widget>[
PopupMenuButton(
onSelected: (value) {
//print the selected option
print(value);
//Update the current choice.
//However, this choice won't be updated in body section since it's a Stateless widget.
choice = value.toString();
},
itemBuilder: (BuildContext context) {
return NavLinks.values.map((link) {
return PopupMenuItem(
value: link,
child: Text(displayString(link)),
);
}).toList();
},
),
],
),
body: Center(
child: Text(
//Print the current choice
choice,
style: TextStyle(fontSize: 30),
),
),
);
}