Halo,
First, I wanna show you my current UI :
And here's the code for red circle function :
InkWell(
onTap: null,
child: Icon(Icons.more_horiz,
size: 18,
color: Color.fromRGBO(0, 0, 0, 0.25),
),
),
What action I needed is to show pop-up menu like this after click the icon, for example :
I need that to create edit and delete with function to navigate to another page, and need to know how to control menu position.
I already check on pub.dev, but it didn't resolve my problem.
Can anyone give me an advice?
Try this code :
the package is here : https://pub.dev/packages/pull_down_button
PullDownButton(
itemBuilder: (context) => [
PullDownMenuItem(
title: 'Menu item',
onTap: () => action(),
),
const PullDownMenuDivider(),
PullDownMenuItem(
title: 'Menu item 2',
onTap: () => action2(),
),
],
position: PullDownMenuPosition.under,
buttonBuilder: (context, showMenu) => CupertinoButton(
onPressed: showMenu,
padding: EdgeInsets.zero,
child: const Icon(CupertinoIcons.ellipsis_circle),
),
);
result :
You can try using PopupMenuButton you can find here an example
Try below code hope its help to you. and used PopupMenuButton
Declare Key Variable:
final GlobalKey menuKey = GlobalKey();
Widget:
InkWell(
onTap: () {
dynamic state = menuKey.currentState;
state.showButtonMenu();
},
child: PopupMenuButton(
key: menuKey,
itemBuilder: (_) => const <PopupMenuItem<String>>[
PopupMenuItem<String>(
child: Text('Show Test'),
value: 'Test',
),
PopupMenuItem<String>(
child: Text('Edit Test Solution'),
value: 'Edit',
),
],
onSelected: (_) {},
),
),
Result->
Related
So I have this ListView where it creates a new ListTile item on click of a button (for now it is a floating action button, but it would need to be changed). Here is the code of the ListView:
body: Container(
),
),
child: BlocConsumer<FoodBloc, List<Food>>(
builder: (context, foodList) {
return ListView.separated(
itemBuilder: (BuildContext context, int index) {
print("foodList: $foodList");
Food food = foodList[index];
return Container(
color: Colors.white60,
child: ListTile(
trailing: Container(
padding: EdgeInsets.only(top: 15.0),
child: IconButton(
icon: Icon(Icons.add),
onPressed: () => null,
),
),
title: Text(food.name, style: TextStyle(fontSize: 30)),
subtitle: Text(
"Calories: ${food.calories} ${food.price} din\nVegan: ${food.isVegan}",
style: TextStyle(fontSize: 20),
),
onTap: () => showFoodDialog(context, food, index)),
);
},
itemCount: foodList.length,
separatorBuilder: (BuildContext context, int index) =>
Divider(color: Colors.black),
);
},
listener: (BuildContext context, foodList) {},
),
),
Here is the floating action button below that creates a new ListTile inside. I would want to have this button functionality besides every type of food like in the image example instead of floating action button (that's not a problem, the layout is):
floatingActionButton: FloatingActionButton(
tooltip: 'Add Food',
child: Icon(Icons.add),
onPressed: () => Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) => FoodForm())),
),
What I would need to do is have the same functionality, but separate the main screen with different types of food (like in the example image). They would all need to be infinitely tileable (to automatically scroll down depending on how much items there are) and would have icon button besides the type (ie drinks) that would add the ListTile to that Column. Here is a rough example of what I have and what I need.
Here is the 'Submit' button that puts the item on the ListView builder in a ListTile, not sure if anything should be changed there:
RaisedButton(
child: Text(
'Submit',
style: TextStyle(color: Colors.blue, fontSize: 16),
),
onPressed: () {
if (!_formKey.currentState.validate()) {
return;
}
_formKey.currentState.save();
Food food = Food(
name: _name,
calories: _calories,
isVegan: _isVegan,
//new var
price: _price,
//added description
description: _description,
);
DatabaseProvider.db.insert(food).then(
(storedFood) =>
BlocProvider.of<FoodBloc>(context).add(
AddFood(storedFood),
),
);
I am facing a problem that my PopupMenuButton not showing when I click on, I tried many solutions but without success.
I am also searched in google but with not results.
I am afraid I am facing a bug.
Here is my code
enum MyMenuEntries { edit, delete }
IconButton(
icon: Icon(Icons.more_vert),
onPressed: () =>
PopupMenuButton<MyMenuEntries>(
onSelected:
(MyMenuEntries entry) {},
itemBuilder:
(BuildContext context) => [
PopupMenuItem<MyMenuEntries>(
value: MyMenuEntries.edit,
child: ListTile(
leading: Icon(Icons.edit),
title: Text("Edit")),
),
PopupMenuItem<MyMenuEntries>(
value: MyMenuEntries.delete,
child: ListTile(
leading: Icon(Icons.delete),
title: Text("Delete")),
),
],
))
Please any answer could help me.
Thanks!
Instead of using an IconButton, you can use the PopUpMenuButton as is and supply the icon to its icon property. It will automatically show the PopUpMenuButton items.
So you should remove the IconButton and your code will be:
PopupMenuButton<MyMenuEntries>(
onSelected:
(MyMenuEntries entry) {},
itemBuilder:
(BuildContext context) => [
PopupMenuItem<MyMenuEntries>(
value: MyMenuEntries.edit,
child: ListTile(
leading: Icon(Icons.edit),
title: Text("Edit")),
),
PopupMenuItem<MyMenuEntries>(
value: MyMenuEntries.delete,
child: ListTile(
leading: Icon(Icons.delete),
title: Text("Delete")),
),
],
icon: Icon(Icons.more_vert),
)
Everything works fine but popupmenubutton isn't closed until any popup item is selected. I do not understand why the popup menu does not close after clicking outside the popup menu and onCanceled does not called.
Please help me.
I have provided the source code below. Thanks.
//Call from Here
StatefulWidget> Scafold(
bottomNavigation,
TabBar
body: widgets>
//under tabBar
child: callAction(
tooltip: "Call Button",
child: Container(
height: double.infinity,
padding: EdgeInsets.all(20),
child: Icon(Icons.call)
),
),
)
//PopupMenuButton widget
enum CallActionType { DataCall, Sim1Call, Sim2Call}
class callAction extends StatelessWidget {
Widget child;
String tooltip;
callAction({#required this.child, #required this.tooltip});
PopupMenuButton<CallActionType>(
elevation: 8,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0)),
onSelected: (CallActionType value) {
setState(() {
print(value);
});
},
//onCanceled didn't call
onCanceled: () {
print('You have not chossed anything');
},
tooltip: widget.tooltip,
offset: Offset(0, 100),
child: widget.child,
itemBuilder: (BuildContext context) => <PopupMenuEntry<CallActionType>>[
new PopupMenuItem<CallActionType>(
value: CallActionType,
child: Text('Action 1'),
),
new PopupMenuItem<CallActionType>(
value: CallActionType,
child: Text('Action 2'),
),
new PopupMenuItem<CallActionType>(
value: CallActionType,
child: Text('Action 3'),
),
],
);
PopupMenu will close smoothly, please see below code for example:
Widget popupMenuButton(){
return PopupMenuButton<String>(
elevation: 50,
padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
icon: Icon(Icons.keyboard_arrow_down, size: 30, color: Colors.black),
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
PopupMenuItem<String>(
value: "One_Val",
child: Text("One_Val"),
),
PopupMenuItem<String>(
value: "Two_Val",
child: Text("Two_Val"),
),
PopupMenuItem<String>(
value: "Three_Val",
child: Text("Three_Val"),
)
],
onSelected: (String value) {
setState(() {
companyName = value;
});
},
);}
Please let me know for any query, Thanks.
Im writing a simple gamebook game in flutter with menu, game and options route. In option route there is button that on pressed should delete all saved games.
Right at this moment Im loading saved games on application launch from SharedPreferences. Right after loading them I set up boolean _savedGame that im using in 'Continue' button in menu route and 'Delete saved games' button in options route to activate or deactivate them. The whole problem is - i dont know how to change variables in menu route from option route. When im creating option route I give it _savedGame so that it knows if it should render active or deactivated button.
PS. Yes, I know that right now im sending option route a copy of _savedGame variable.
Menu route option page button.
RaisedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => OptionsPage(_savedGame),
),
),
Option page
class OptionsPageState extends State<OptionsPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
"Options",
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.blueGrey[900],
),
body: Container(
alignment: Alignment.center,
color: Colors.cyan,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child:
Text('Delete saved games', style: TextStyle(fontSize: 40)),
onPressed:
widget.isGameSaved ? () => _showWarning(context) : null,
),
const SizedBox(height: 30),
RaisedButton(
child: Text('Back', style: TextStyle(fontSize: 40)),
onPressed: () {
Navigator.pop(context);
},
),
])),
),
);
}
Future<void> _showWarning(BuildContext context) {
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Are you sure you want to delete saved game?'),
actions: <Widget>[
FlatButton(
child: Text('No'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: Text('Yes'),
onPressed: () {
saveGame('empty');
Navigator.of(context).pop();
setState(() {
widget.isGameSaved = false;
});
},
),
],
);
},
);
}
}
How do I "setState" for variables in different routes?
What you could do is have an InheritedWidget (call it say GameStateWidget) above your Navigator (or MaterialApp if you're using its navigator). In the InheritedWidget have a ValueNotifier, say savedGame that has the value you want to share.
Then in the route where you need to set the value
GameStateWidget.of(context).savedGame.value = ...
And in the route where you need the value
ValueListenableBuilder(
valueListenable: GameStateWidget.of(context).savedGame,
builder: (context, savedGameValue, child) => ...
)
I'm trying to get a popupmenu under a ListTile. The title displays a description, the subtitle displays the selected value with some message and the onTap opens the popupmenu in which a user can select a value.
I tried putting a DropdownButtonHideUnderline in the subtitle, but this displays an arrow and does not respond to the ListTile onTab obviously.
How can I get a popupmenu on a ListTile?
Maybe you can try PopuMenuButton,
PopupMenuButton<String>(
onSelected: (String value) {
setState(() {
_selection = value;
});
},
child: ListTile(
leading: IconButton(
icon: Icon(Icons.add_alarm),
onPressed: () {
print('Hello world');
},
),
title: Text('Title'),
subtitle: Column(
children: <Widget>[
Text('Sub title'),
Text(_selection == null ? 'Nothing selected yet' : _selection.toString()),
],
),
trailing: Icon(Icons.account_circle),
),
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
const PopupMenuItem<String>(
value: 'Value1',
child: Text('Choose value 1'),
),
const PopupMenuItem<String>(
value: 'Value2',
child: Text('Choose value 2'),
),
const PopupMenuItem<String>(
value: 'Value3',
child: Text('Choose value 3'),
),
],
)
Take a look at How to open a PopupMenuButton?