I want to pass screens which i have built in this navigator onTap
onTap: () => Navigator.push(context,
MaterialPageRoute(builstrong textder: (context) => QuestionPaperScreen()))
There is a QuestionPaperScreen() and I want to pass here a screen which is received as a variable on Function call
How can I do it?
In QuestionPaperScreen you can define and variable and mark it as required and pass it from this screen
class QuestionPaperScreen extends StatelessWidget {
final String routeName;
const QuestionPaperScreen({Key? key, required this.routeName}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container();
}
}
Then on tap you can use
onTap: (){
Navigator.push(context, MaterialPageRoute(builder: (_)=>QuestionPaperScreen(routeName:'/routeNameHere')));//pass the route name that you received from a function here
},
Related
I am trying switch to a different screen in Flutter project using onPressed but it is not generating any outcome not sure what is the reason.
Here is the homescreen page:
onPressed: () {
const User_Profile();
print("Hello");
},
Here is the user profile:
class User_Profile extends StatefulWidget {
const User_Profile({Key? key}) : super(key: key);
#override
State<User_Profile> createState() => _user_profileState();
}
class _user_profileState extends State<User_Profile> {
#override
Widget build(BuildContext context) {
return const Text("User Profile");
}
}
Question:
How to switch screens using Onpressed? What am I doing wrong noting that the word Hello for debugging is printed everytime.
Try below code and use Navigator.push refer navigation
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => User_Profile(),
),
);
},
child: const Text('User Profile'),
),
You have to use a function instead of your class like this:
Navigator.push(context, MaterialPageRoute(builder: (context)=>User_profile()));
call this:
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context)=>User_profile()));
},
instead of this:
onPressed: () {
const User_Profile();
print("Hello");
},
as you know you can't go to a specific page by calling the constructor method in a class. you have 2 ways:
use Navigator.push like this:
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => User_Profile(),
),
);
and you can send the parameters to the next page by sending by constructor parameters like: User_Profile(name: 'yourName').2) you can use Navigator.pushNamed. you can define routeName in your main class of the project like this:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(
MyApp(),
);
}
class MyApp extends StatefulWidget {
MyApp({Key? key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
canvasColor: Colors.transparent,
),
initialRoute: '/',
routes: {
'/': (context) => Splash(),
'/user_profile': (context) => User_Profile(),
},
);
}
}
as you see you defined a routeName '/user_profile' and you can use Navigator.pushNamed and if you want to pass parameters to the next page you have to use arguments like this:
Navigator.pushNamed(
context,
'/user_profile',
arguments: {"name" : "yourName"},);
and this code is for getting the arguments that you've passed in your User_Profile :
var arguments = ModalRoute.of(context)!.settings.arguments as Map;
var name = arguments['name'] as String;
I recommend you to use the second way to know all your routes of your projects.
Good Luck;)
I would like to update a page other than the one in which the user presses the button, I know that to update the page itself just use the
setState (() {})
but what I want to do is update the HomePage when the user presses a button that is on the main.dart page. How can I solve?
What I thought and that it works but badly is to use the
Navigator.push (context, MaterialPageRoute (builder: (context) => const MyApp ()));
when the user presses the button, and doing so it works because it updates my MyApp (main.dart), the problem is that when they press the button in this way you see the same animation as when you open the app and it is very ugly.
you can pass a function with setState in it to the other page and run the function after click the buttton
something like this:
class Startpage extends StatefulWidget {
const Startpage({super.key});
#override
State<Startpage> createState() => StartpageState();
}
class StartpageState extends State<Startpage> {
#override
Widget build(BuildContext context) {
return TextButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondPage(updateStartPage: () {
setState(() {
//add your logic
});
})),
),
child: const Text("navigate to second page"));
}
}
class SecondPage extends StatelessWidget {
final Function updateStartPage;
const SecondPage({super.key, required this.updateStartPage});
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => updateStartPage(),
child: const Text("update parent"),
);
}
}
I'm trying to make a custom ElevatedButton widget whose constructor will receive one of two options:
either a new page to push into the Navigator (my custom StatefulWidget),
or a callback method to override the button's onPressed entirely.
I tried to create two separate constructors - one for each of the possibilities but the constructor which is supposed to receive the callback method doesn't seem to get it. When I debug the code I see the received object is Closure.
What am I doing wrong?
import 'package:flutter/material.dart';
// ignore: must_be_immutable
class OrdinaryButton extends StatelessWidget {
final String? text;
Widget? goto;
late Function()? onPressed;
OrdinaryButton({this.text, this.goto});
OrdinaryButton.overrideOnPressed({this.text, required this.onPressed})
{
this.goto = null;
}
#override
Widget build(BuildContext context) {
return ElevatedButton(
child: Text("$text"),
onPressed: () {
if(goto != null)
{
print("LOG: opening a new page...");
Navigator.push(context, MaterialPageRoute(builder: (context) => goto!));
}
else if(this.onPressed != null)
{
print("LOG: calling a custom function...");
this.onPressed; // This has the 'Closure' object instead of my callback.
}
},
);
}
}
you missed "!()"after "onPressed" your code works for me
hello() {
print("hello");
}
//Call this widget in my code
Column(
children: [
OrdinaryButton.overrideOnPressed(
onPressed: hello,
text: "Salut",
)
],
),
class OrdinaryButton extends StatelessWidget {
final String? text;
Widget? goto;
late Function()? onPressed;
OrdinaryButton({Key? key, this.text, this.goto}) : super(key: key);
OrdinaryButton.overrideOnPressed({this.text, required this.onPressed}) {
goto = null;
}
#override
Widget build(BuildContext context) {
return ElevatedButton(
child: Text("$text"),
onPressed: () {
if (goto != null) {
print("LOG: opening a new page...");
Navigator.push(
context, MaterialPageRoute(builder: (context) => goto!));
} else if (onPressed != null) {
print("LOG: calling a custom function...");
onPressed!();
//you missed "!()" here after onPressed
}
},
);
}
}
I'm Working on Project Where there is A screen For viewing the user Profile and another screen for Editing Profile. I'm using onGenerateRoute Method for Routing and know I can parse an argument and send it over.
How I can use Call Back Function ValueChange with onGenerateRoute Method?
Navigate to the EditingProfile Page and pass the Function as an argument:
Navigator.pushNamed(context, "/editingprofile", arguments: () {
print("Function called");
});
In the onGenerateRoute pass the argument to the EditingProfile either as constructor param and call the variable directly
Route<dynamic>? generateRoute(RouteSettings settings) {
final args = settings.arguments;
switch (settings.name) {
case "/editingprofile":
return MaterialPageRoute(
builder: (context) => EditingPage(settings.arguments as Function));
}
}
class EditingPage extends StatelessWidget {
Function callback;
SecondPage(this.callback, {Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: OutlinedButton(
onPressed: (){
callback.call();
},
child: Text("Press me"),
),
);
}
}
or pass it inside the MaterialPageRoute as settings param and get the function with ModalRoute
Route<dynamic>? generateRoute(RouteSettings settings) {
final args = settings.arguments;
switch (settings.name) {
case "/editingprofile":
return MaterialPageRoute(
settings: settings,
builder: (context) => EditingProfile());
}
}
class EditingPage extends StatelessWidget {
EditingPage ({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
Function callback = ModalRoute.of(context)!.settings.arguments as Function;
return Scaffold(
body: OutlinedButton(
onPressed: (){
callback.call();
},
child: Text("Press me"),
),
);
}
}
My final goal is to have a userName variable from one dart file transferred to the other dart file.
Firebase Authentication will only take the email and password inputs so I need to pass the userName variable as an argument into another file that is called after the users email has been verified.
I have been trying to find videos and documentation online, most of what I found is trying to put the data into a list (which I would like to avoid). I don't understand the "this." getter function in flutter yet, I don't know if it's necessary to solve this problem. Let me know if there's anything I can clarify, I hope I'm overlooking something simple.
Dart File #1
onPressed: () => signUp(_email, _password).then((_) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => Verify(_userName)));
}),
Dart File #2
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class Verify extends StatefulWidget {
const Verify(String _userName, {Key? key}) : super(key: key);
#override
_VerifyState createState() => _VerifyState();
}
class _VerifyState extends State<Verify> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child:
Text('Here is your variable $_userName please verify'),
),
);
}
I guess you're asking about passing arguments(any object) between different screens.
You can do this easily by passing it in RouteSettings, you can pass any object (String, int, map) and then fetch it in the build method of another Screen.
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return TextButton(
onPressed: () => Navigator.push(
context, MaterialPageRoute(
builder: (context) => HomeScreen(),
settings: const RouteSettings(arguments: 'username')),), //arguments
child: Text('Hello, World!',
style: Theme.of(context).textTheme.headline4,
),
);
}
}
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
final args = ModalRoute.of(context)!.settings.arguments as String; //arguments
return TextButton(
onPressed: () {},
child: Text(args,
style: Theme.of(context).textTheme.headline4,
),
);
}
}