How to navigate to a different page using MenuItem in Flutter? - flutter

I'm new to Flutter, I have a list of MenuItems in Drawer like below.
MenuItem selectedMenuItem;
List<MenuItem> menuItems = [
MenuItem(title: 'Contact', items: [
MenuItem(title: 'Contact Us'),
MenuItem(title: 'Call center'),
MenuItem(title: 'WhatsApp'),
]),
MenuItem(title: 'language'),
MenuItem(title: 'Customer'),
];
I want to open a different page when each item is clicked. What should be my next step? Any ideas?
subItems(BuildContext context) {
return selectedMenuItem.items.map(
(item) => MaterialButton(
onPressed: () {
redirectItem(item);
},
child: Row(
children: [
Text(
item.title,
),
],
),
),
);
} style: TextStyle(fontSize: 14),
);
}

Welcome to the Flutter Community! I don't see your complete code so I guess you're already able to perform something when onPressed() is triggered.
You can navigate to another widget using this code:
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => YourWidget(),
),
);
},

Related

Flutter UI Create menu with function after click icon more

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->

Use OnLongPress and OnPress differently in flutter datatable?

Is there a way to do different actions on a DataTable object depending on LongPress vs ShortPress?
ShortPress -- Present details (read only),
LongPress -- Present details (read-write).
I do
await Navigator.push(
context, new MaterialPageRoute(builder: (context) => new Page2(dataRow, editMode)));
from the DataTable's OnSelectChanged,but I don't know how to set "editmode" based on a longPress vs a shortPress (or double-tap)...
Adding a GestureDetector to every DataCell may not be the best solution but it should work
DataTable(columns: [
DataColumn(
label: Text("Name"),
),
DataColumn(
label: Text("Age"),
),
DataColumn(
label: Text("Year"),
),
], rows: [
DataRow(cells: [
DataCell(
GestureDetector(
child: Text("Ross"),
onTap: () {
print('Tap');
},
onLongPress: () {
print('Long Press');
},
),
),
DataCell(
GestureDetector(
child: Text("28"),
onTap: () {
print('Tap');
},
onLongPress: () {
print('Long Press');
},
),
),
DataCell(
GestureDetector(
child: Text("2003"),
onTap: () {
print('Tap');
},
onLongPress: () {
print('Long Press');
},
),
),
]),
]);
}

Title is not displayed in AlertDialog Widget Flutter

Provider.of<Products>(context, listen: false)
.addProducts(_editedProduct)
.catchError((error) {
return showDialog<Null>(
context: context,
builder: (ctx) {
return AlertDialog(
title: Text(
'An error occurred',
),
content: Text('SomethingWent Wrong'),
actions: [
FlatButton(
child: Row(
children: [
Icon(Icons.close),
Text('Close'),
],
),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
},
);
}).then((value) {
setState(() {
_isLoading = false;
});
Navigator.of(context).pop();
});
I was able to display an alert dialogue but I coundn't show the title. I am unable to find the reason.
Everything is working fine except the title is not displaying.
Alert Dialog Screenshot
Happened to me too.
Give the text a color, I think the default is white so you can't see it.
return AlertDialog(
title: Text('AlertDialog Title'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('This is a demo alert dialog.'),
Text('Would you like to approve of this message?'),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Approve'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
Try this and see if it works.

How to use onTap or onPressed in PopupMenuItem

How can we implement use of onTap or onPressed in PopupMenuItem
Here is my code:
actions: <Widget>[
PopupMenuButton(
icon: Icon(Icons.settings),
itemBuilder: (context) => [
PopupMenuItem(
child: Text("Settings"),
),
PopupMenuItem(
child: Text("Flutter.io"),
),
PopupMenuItem(
child: Text("Google.com"),
),
],
),
]
I want to navigate to SettingPage() on tapping or clicking Settings PopupMenuItem.
I am getting this error even after following a solution mentioned below and even after importing dart:js
Error: Not found: 'dart:js'
import 'dart:js';
Here are my dependencies:
import 'package:bfdi_app/Profile/editProfile.dart';
import 'package:bfdi_app/models/user.dart';
import 'package:bfdi_app/services/collection.dart';
import 'package:bfdi_app/settings.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'dart:js';
Just add this to your PopupMenuButton:
onSelected: (result) {
if (result == 0) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SettingPage()),
);
}
},
And change your setting button to:
PopupMenuItem(
child: Text("Settings"),
value: 0,
),
There is a property called onSelected, you should use it, it handles onTap event.
PopupMenuButton(
icon: Icon(Icons.settings),
onSelected: (newValue) { // add this property
setState(() {
_value = newValue; // it gives the value which is selected
});
},
itemBuilder: (context) => [
PopupMenuItem(
child: Text("Settings"),
value: 0,
),
PopupMenuItem(
child: Text("Flutter.io"),
value: 1,
),
PopupMenuItem(
child: Text("Google.com"),
value: 2,
),
],
)
I faced similar issues while navigating the screen using pop up menu button and I solve the issues by putting this method inside the onTap callback of PopupMenuItem:
onTap: (){
WidgetsBinding.instance!.addPostFrameCallback((_) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ScreenName();
},
),
);
});
}
There is now an onTap() for PopupMenuItem.
PopupMenuButton(
itemBuilder: (context) => [
PopupMenuItem(
child: Text("tap me"),
onTap: () => print("TAP"),
)
],
),
-Edited based on comment-
That's it :
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var items = [{'name':'Settings','value':0}, {'name':'Flutter.io','value':1}, {'name':'Google.com',,'value':2}];
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: PopupMenuButton(
onSelected: (x) {
if(x==0){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SettingPage()), );}
},
icon: Icon(Icons.settings),
itemBuilder: (context) => items
.map<PopupMenuItem>((element) => PopupMenuItem(
child: Text(element['name]),
value: element['value'],
))
.toList()),
));
}
}
Callable value.
PopupMenuButton(
icon: Icon(Icons.settings),
onSelected: (value) {
value();
},
itemBuilder: (context) => [
PopupMenuItem(
child: Text('Settings'),
value: () {
debugPrint('open Settings');
},
),
PopupMenuItem(
child: Text('Flutter.io'),
value: () {
debugPrint('goto Flutter.io');
},
),
],
)
Use inheritance when showing popup with showMenu(...)
class PopupItem<T> extends PopupMenuItem<T> {
final Function() onTap;
PopupItem({this.onTap, Widget child, Key key})
: super(child: child, key: key);
#override
_PopupItemState<T> createState() => _PopupItemState<T>();
}
class _PopupItemState<T> extends PopupMenuItemState<T, PopupItem<T>> {
#override
void handleTap() {
widget.onTap?.call();
super.handleTap();
}
}
Usage:
Widget _itemDelete() => PopupItem(
onTap: () {
// Handle tap here
},
child: Text(...)
);
onTap: (){
WidgetsBinding.instance!.addPostFrameCallback((_) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context)=>Page())):
},
),
);
});
}
PopupMenuButton (
padding: EdgeInsets.zero,
icon:const Icon(Icons.keyboard_arrow_down_outlined,color: Color.fromRGBO(34, 178, 232, 1)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15.0))
),
onSelected: (x){
if (x=="Edit User") {
Get.to(EditUserPage());
}
else if(x=="Login History"){
Get.to(EditUserPage());
}
else if(x=="Change Password"){
Get.to(EditUserPage());
}
else if(x=="Deactivate User"){
Get.to(EditUserPage());
}
},
itemBuilder: (BuildContext context) => <PopupMenuEntry >[
PopupMenuItem (
onTap: (){},
value:"Edit User",
child: Row(
children: [
svgWedget(url:"assets/svg/edit.svg"),
SizedBox(width: 10,),
Text("Edit User"),
],
),
),
PopupMenuItem (
onTap: ( )async{},
value:"Login History",
child: Row(
children: [
svgWedget(url:"assets/svg/calendar.svg"),
SizedBox(width: 10,),
Text("Login History"),
],
),
),
PopupMenuItem (
onTap: ()async{},
value:"Change Password",
child: Row(
children: [
SvgPicture.asset("assets/svg/lock.svg",color: Color.fromRGBO(195, 172, 255, 1),),
SizedBox(width: 10,),
Text("Change Password"),
],
),
),
PopupMenuItem (
onTap: ()async{},
value:"Deactivate User",
child: Row(
children: [
svgWedget(url:"assets/svg/trash.svg"),
SizedBox(width: 10,),
Text("Deactivate User"),
],
),
),
]
),

How to pass a variable reference between different routes?

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) => ...
)