Flutter, Fluro "anonymous closure" - flutter

I just started learning Dart/Flutter, and I have been advised to use the Fluro package for navigation.
Is it possible to switch between 2 StatefulWidget "pages" with Fluro router?
I had no problems when switching between stateless widgets, but when I've tried to make them stateful, I got this error: "The return type 'Page2' isn't a 'Widget', as defined by anonymous closure." I can't figure out what I should change in the code.
class FluroRouter {
static Router router = Router();
static void setupRouter() {
router.define("Page2", handler: page2Handler);
router.define("Page1", handler: page1Handler);
}
static Handler page2Handler = Handler(
handlerFunc: (BuildContext context, Map<String, dynamic> params) => Page2());
static Handler page1Handler = Handler(
handlerFunc: (BuildContext context, Map<String, dynamic> params) => Page1());
}
class BasePage2 extends StatefulWidget {
#override
State createState() {
return Page2();
}
}
class Page2 extends State<BasePage2> {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome',
home: Scaffold(
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.pink,
child: Icon(Icons.router),
onPressed: () {
Navigator.pushNamed(context, 'Page1');
},
),
appBar: AppBar(
title: Text("Page 2"),
),
body: Center(
child: Text("Page 2"),
)),
);
}
}
//Page 1 looks the same, only the text says "Page 1"
Thank you in advance for any suggestions.

You need to pass the StatefulWidget and not the State:
... => BasePage2()
... => BasePage1()

Related

Is it possible to display different link pages by Navigator.push?

I am developing by flutter for web.
It is currently possible to go from the main page to the profile page, but is it possible to keep those URLs separate?
For example:
Main page : https:// testapp.com/home
Profile page: https:// testapp.com/profile
When I execute the profilePage() function, Navigator.push will take me to the Profile page.
void profilePage() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => showProfile(),
),
);
}
showProfile is executed with a different dart file to complete the page navigation.
class showProfile extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
title: const Center(
child: Text("Test App",
style:
TextStyle(color: Colors.black)),
)),
body: Container(
height: double.infinity,
color: Colors.white,
),
);
}
}
Currently, the Main page and Profile page have the same URL (https:// testapp.com/#/).
Therefore, even if the user types testapp.com/profile, they cannot jump to the profile page.
My purpose is to go to a different URL in Navigator.
Thank you.
Add this dependancy/plugin.
Now, Create a file with name routing.dart and add this code:-
class FluroRouting {
static final router = FluroRouter();
static Handler _profileHandler = Handler(
handlerFunc: (BuildContext context, Map<String, dynamic> params) =>
Profile());
static Handler _homeHandler = Handler(
handlerFunc: (BuildContext context, Map<String, dynamic> params) =>
HomePage());
static void setupRouter() {
router.define('/home', handler: _homeHandler,);
router.define('/profile', handler: _profileHandler,);
router.notFoundHandler = Handler(
handlerFunc: (BuildContext? context, Map<String, dynamic> params) =>HomePage()
);
}
static void navigateToPage({String routeName,BuildContext context}) {
router.navigateTo(context, routeName, transition: TransitionType.none);
}
static void pushAndClearStackToPage({String routeName,BuildContext context}) {
router.navigateTo(context, routeName, clearStack: true,transition: TransitionType.none);
}
}
Now you need to initialize and setup these routes so modify your void main as:-
void main()async {
FluroRouting.setupRouter();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'My Website',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/home',
onGenerateRoute: FluroRouting.router.generator,
);
}
}
And whenever you need to navigate then simply use the below code:-
FluroRouting.navigateToPage(routeName:"/profile",context:context);
This web site helped my issue.
https://medium.com/flutter/flutter-web-navigating-urls-using-named-routes-307e1b1e2050
Solution;
Write the following code in the main function.
void main() {
runApp(MaterialApp(
initialRoute: '/',
routes: {
'/profile': (context) => ProfilePage(),
},
title: "test",
home: (),
));
}
Declare the following in the widget whose URL you want to be "domain.com/ profile" (To be exact, "domain.com/#/profile").
class ProfilePage extends StatelessWidget {
static const String route = '/profile';
}
And finally, call this.
onPressed: () {
Navigator.of(context).pushNamed(ProfilePage.route);
},

Flutter Errors: Undefined name "context"

I receive some errors when I try to push my flutter page from neighbourhoodList to individual neighbourhoods (e.g. neighbourhoodlist_admirality).
In my neighbourhoodlist, I would like to navigate to the individual neighbourhood pages when the user has clicked on the relevant neighbourhood. As I have not build the individual neighbourhood pages yet, I have linked them to an example page i.e. NeighbourhoodAdmirality.
This is my code for the neighbourhoodlist page:
import 'package:flutter/material.dart';
import 'indv_neighbourhoods/neighbourhoodlist_admirality.dart';
class NeighbourhoodList extends StatefulWidget {
NeighbourhoodList({ this.name = "name"});
final String name;
#override
_NeighbourhoodListState createState() => _NeighbourhoodListState();
}
class _NeighbourhoodListState extends State<NeighbourhoodList> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Neighbourhoods',
),
),
body: _buildListView(context),
);
}
ListView _buildListView(BuildContext context){
return ListView.builder(
itemCount: allNeighbourhoods.length,
itemBuilder: (BuildContext content, int index) {
NeighbourhoodList neighbourhoodlist = allNeighbourhoods[index];
return NeighbourhoodListTile(neighbourhoodlist);
});
}
}
class NeighbourhoodListTile extends ListTile {
NeighbourhoodListTile(NeighbourhoodList neighbourhoodlist)
: super(
title: Text(neighbourhoodlist.name),
trailing: Icon(Icons.arrow_forward),
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => NeighbourhoodAdmiralty(neigh1)),
);
}
);
}
List<NeighbourhoodList> allNeighbourhoods = [
NeighbourhoodList(name: 'Admiralty'),
NeighbourhoodList(name: 'Aljunied'),
NeighbourhoodList(name: 'Ang Mo Kio'),
];
This is my code for an example page that I want to direct my neighbourhoodlist to when each individual neighbourhood is directed.
import 'package:flutter/material.dart';
class NeighbourhoodAdmiralty extends StatefulWidget {
final String neigh1;
NeighbourhoodAdmiralty(this.neigh1);
#override
_NeighbourhoodAdmiraltyState createState() => _NeighbourhoodAdmiraltyState();
}
class _NeighbourhoodAdmiraltyState extends State<NeighbourhoodAdmiralty> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Admiralty"),
),
body: Center(child: Text('This is the individual neighbourhood page'),
),
);
}
}
As I am still a beginner, I am facing some errors and have a few questions on these:
Error 1 on neighbourhoodlist.dart: "Undefined name 'context'" under Navigator.push --> not sure why this happens as I have already passed the BuildContext in my methods above
Error 2 on neighbourhoodlist.dart: "Undefined name 'neigh1'" under Navigator.push --> I would like to redirect the neighbourhoodlist.dart page to the individual neighbourhood sheets but I'm not sure what I pass here, I have tried 'neigh1' (my variable in neighbourhoodlist_admirality), 'name' - the variable in NeighbourhoodList, and 'index' 0 the variable inNeighbourhoodListState but none of them seem to work so far.
Appreciate all your help in resolving this and thanks in advance !
When you do
class NeighbourhoodListTile extends ListTile {
NeighbourhoodListTile(NeighbourhoodList neighbourhoodlist)
: super(
title: Text(neighbourhoodlist.name),
trailing: Icon(Icons.arrow_forward),
onTap: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => NeighbourhoodAdmiralty(neigh1)));
}
);
}
you can't access context in onTap because Flutter hasn't yet provided one to you in this point. If you need the context, use a StatelessWidget instead, where you can access it in the build method:
class NeighbourhoodListTile extends StatelessWidget {
final NeighbourhoodList neighbourhoodlist;
const NeighbourhoodListTile(this.neighbourhoodlist);
#override
Widget build(BuildContext context) {
// Here's your context ^^^^^^^
return ListTile(
title: Text(neighbourhoodlist.name),
trailing: Icon(Icons.arrow_forward),
onTap: (){
Navigator.push(context, MaterialPageRoute(
builder: (context) => NeighbourhoodAdmiralty(neigh1)));
}
);
}
}
As to your second error, there is also no neigh1 variable at this point. I don't know what your logic is, but I think you want to replace it with neighbourhoodlist.name:
class NeighbourhoodListTile extends StatelessWidget {
final NeighbourhoodList neighbourhoodlist;
const NeighbourhoodListTile(this.neighbourhoodlist);
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(neighbourhoodlist.name),
trailing: Icon(Icons.arrow_forward),
onTap: (){
Navigator.push(context, MaterialPageRoute(
builder: (context) => NeighbourhoodAdmiralty(neighbourhoodlist.name)));
}
);
}
}

Using Navigator with a bottomNavigationBar

What's the correct way of setting up navigation architecture named routes while using a bottomNavigationBar?
Here's my current setup but I feel there's a better way of doing it:
main.dart:
onGenerateRoute: (settings) {
return MaterialPageRoute(
settings: settings,
builder: (context) {
switch (settings.name) {
case NamedRoutes.splashScreen:
return SplashScreen();
case NamedRoutes.login:
return LoginPage();
case NamedRoutes.mainApp:
return NavigatorSetup();
default:
throw Exception('Invalid route: ${settings.name}');
}
});
navigatorSetup.dart:
IndexedStack(
index: Provider.of<RoutesProvider>(context).selectedViewIndex,
children: [FirstMain(), SecondMain(), ThirdMain(), FourthMain()],
), bottomNavigationBar...
in each main files there is the following setup
class FirstMain extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Navigator(
key: Provider.of<RoutesProvider>(context).homeKey,
onGenerateRoute: (settings) {
return MaterialPageRoute(
settings: settings,
builder: (context) {
switch (settings.name) {
case '/':
case NamedRoutes.mainPage:
return MainPage();
case NamedRoutes.singleMainPage:
return SingleMainPage();
default:
throw Exception('Invalid route: ${settings.name}');
}
},
);
},
);
}
}
Then my routes provider looks like this:
class RoutesProvider extends ChangeNotifier {
int _selectedViewIndex = 0;
get selectedViewIndex => _selectedViewIndex;
set selectedViewIndex(int newIndex) {
_selectedViewIndex = newIndex;
notifyListeners();
}
GlobalKey _mainKey = GlobalKey<NavigatorState>();
GlobalKey _homeKey = GlobalKey();
GlobalKey _secondKey = GlobalKey();
GlobalKey _thirdKey = GlobalKey();
GlobalKey _fourthKey = GlobalKey();
get mainKey => _mainKey;
get homeKey => _homeKey;
get secondKey => _secondKey;
get thirdKey => _thirdKey;
get fourthKey => _fourthKey;
}
The way I'm currently changing routes when on another page of the indexedStack
final RoutesProvider routesProvider = Provider.of<RoutesProvider>(context, listen: false);
final GlobalKey thirdKey = routesProvider.thirdKey;
routesProvider.selectedViewIndex = 2;
Navigator.pushReplacementNamed(thirdKey.currentContext, NamedRoutes.third);
The better way to navigate
Creating a route_generator
import 'package:flutter/material.dart';
import 'package:routing_prep/main.dart';
class RouteGenerator {
static Route<dynamic> generateRoute(RouteSettings settings) {
// Getting arguments passed in while calling Navigator.pushNamed
final args = settings.arguments;
switch (settings.name) {
case '/':
return MaterialPageRoute(builder: (_) => FirstPage());
case SecondPage.routeName:
// Validation of correct data type
if (args is String) {
return MaterialPageRoute(
builder: (_) => SecondPage(
data: args,
),
);
}
// If args is not of the correct type, return an error page.
// You can also throw an exception while in development.
return _errorRoute();
default:
// If there is no such named route in the switch statement, e.g. /third
return _errorRoute();
}
}
static Route<dynamic> _errorRoute() {
return MaterialPageRoute(builder: (_) {
return Scaffold(
appBar: AppBar(
title: Text('Error'),
),
body: Center(
child: Text('ERROR'),
),
);
});
}
}
As you can see, you've moved from having bits of routing logic everywhere around your codebase, to a single place for this logic - in the RouteGenerator. Now, the only navigation code which will remain in your widgets will be the one pushing named routes with a navigator.
Before you can run and test the app, there's still a bit of a setup to do for this RouteGenerator to function.
main.dart
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
...
// Initially display FirstPage
initialRoute: '/',
onGenerateRoute: RouteGenerator.generateRoute,
);
}
}
class FirstPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
...
RaisedButton(
child: Text('Go to second'),
onPressed: () {
// Pushing a named route
Navigator.of(context).pushNamed(
SecondPage.routeName,
arguments: 'Hello there from the first page!',
);
},
)
...
}
}
class SecondPage extends StatelessWidget {
static const routeName = "/second";
// This is a String for the sake of an example.
// You can use any type you want.
final String data;
SecondPage({
Key key,
#required this.data,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Routing App'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'Second Page',
style: TextStyle(fontSize: 50),
),
Text(
data,
style: TextStyle(fontSize: 20),
),
],
),
),
);
}
}

Error BlocProvider.of() called with a context That doesn't contain A bloc of type UserBloc

Anyone know what should I do with this? I making a user's listview, it should show appbar, tabbar userlist, user group, and the list of all users.
When I'm not using model and repository and just put the data manually on the users_page.dart, everything was fine, the layout showing. But it's happen idk what to do.
If you want to get the BLoC from a BlocProvider.of(context) you need to provide that BLoC somewhere on top of your current context. You need something like this:
BlocProvider(
create: (BuildContext context) => UsersBloc(),
child: child(),
);
In one of the ancestors of your UsersPage. Basically you need to tell from where to get an instance of your BLoC in that widget tree. Normally i write those BlocProviders in the MaterialApp, ensuring that every page will have those blocs in theirs context.
this is my UsersBloc:
import 'package:bloc/bloc.dart';
import 'package:merchant/feature/bloc/users/users_event.dart';
import 'package:merchant/feature/bloc/users/users_state.dart';
class UsersBloc
extends Bloc < UsersEvent, UsersState > {
int currentIndex = 0;
#override
UsersState get initialState => UsersLoading();
#override
Stream < UsersState > mapEventToState(UsersEvent event) async * {
if (event is UsersStarted) {
this.add(UsersTapped(index: this.currentIndex));
}
if (event is UsersTapped) {
this.currentIndex = event.index;
yield CurrentIndexChanged(currentIndex: this.currentIndex);
yield UsersLoading();
if (this.currentIndex == 0) {
// String data = await UsersRepository();
yield UsersListLoaded(text: "UsersList");
}
if (this.currentIndex == 1) {
// String data = await UsersRepository();
yield UsersGroupLoaded(text: "UsersGroup");
}
if (event is UsersDetailTapped) {
yield UsersDetailLoaded(text: "UserDetail");
}
}
}
}
this is my UsersPage :
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:merchant/component/widget/loading_widget.dart';
import 'package:merchant/feature/bloc/users/users_bloc.dart';
import 'package:merchant/feature/bloc/users/users_event.dart';
import 'package:merchant/feature/bloc/users/users_state.dart';
import 'package:merchant/feature/splash_page.dart';
import 'package:merchant/feature/ui/users/users_list_tab.dart';
import 'package:merchant/feature/ui/users/users_group_tab.dart';
class UsersPage extends StatelessWidget {
final String text;
const UsersPage(this.text): super();
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Text(
"Users (UKSW)",
style: TextStyle(color: Colors.white),
),
bottom: TabBar(
onTap: (index) => BlocProvider.of < UsersBloc > (context).add(UsersTapped(index: index)),
isScrollable: true,
labelColor: Colors.white,
unselectedLabelColor: Colors.black54,
tabs: [
Tab(text: "User List"),
Tab(text: "User Group"),
],
),
actions: [
IconButton(icon: Icon(Icons.search),
onPressed: () {}
)
]
),
body: BlocBuilder < UsersBloc, UsersState >
( //bloc: BlocProvider.of<UsersBloc>(context),
builder: (context, state) {
if (state is UsersLoading) {
return LoadingWidget(visible: true);
}
if (state is UsersListLoaded) {
return UsersList();
} else if (state is UsersGroupLoaded) {
return UsersGroup();
}
return SplashPage();
}
)
));
}
}
this is my users_model.dart :
import 'dart:convert';
class UsersModel {
String name, username;
UsersModel({
this.name,
this.username
});
factory UsersModel.fromJson(Map<String, dynamic> json) => UsersModel(
name: json['name'],
username: json['username']
);
}
can you try initialising your bloc at the root of your app something like this
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: BlocProvider< UsersBloc >(
create: (context) => UsersBloc(),
child: UsersPage(),
),
);
}
}
then in your UsersPage file initialise bloc and assign it to variable and use it across.
Widget build(BuildContext context) {
final UsersBloc usersBloc = BlocProvider.of<UsersBloc>(context);
return DefaultTabController(
length: 2,
...
bottom: TabBar(
onTap: (index) => usersBloc.add(UsersTapped(index: index),
...)
}
I have the same problem if you are calling from a non-bloc (Normal class) to a new bloc class without any bloc changes to the main class (Multi-bloc provider to runApp). Then add
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
BlocProvider<UsersBloc>(
create: (context) => UsersBloc(),
child: UsersBlocPage(),
),
));
This to your calling sequence. It works for me

Flutter - Get data using pushName

I´m trying to send data with pushName. Then i try to get this data to show in a Toast message.
PushName
Navigator.pushNamed(
context,
'/navigator',
arguments: <String, String>{
'instalation': widget.instalation,
'message': DemoLocalizations.of(context)
.text('cancel-message') +
" " +
widget.datameterValue.toString(),
},
);
Trying to retrieve data
class Navigation extends StatefulWidget {
final ConnectionPage args;
Navigation({Key key, this.message, this.instalation, this.args}) : super(key: key);
}
class _NavigationState extends State<Navigation> {
void initState() {
super.initState();
print(widget.args); //NULL
final snackBar = SnackBar(
duration: Duration(seconds: 5),
content: Text(widget.args.messsage+ '.', textAlign: TextAlign.center),
backgroundColor: Colors.red[700],
);
key.currentState.showSnackBar(snackBar);
}
}
The problem: Return null.
So: What is the right way to get data using pushName? In the documentation show how can we get data inside Scaffold but i need to get data in the initState.
UPDATE
Routes
routes: {
'/login': (context) => LoginPage(),
'/navigator': (context) => Navigation(),
'/home': (context) => HomePageScreen(),
'/connect': (context) => ConnectionPage(),
},
UPDATE 2
I try something like this
Navigator.pushNamed(
context,
'/navigator',
arguments: Navigation(
instalation: widget.instalation,
message: DemoLocalizations.of(context)
.text('cancel-message') +
" " +
widget.datameterValue.toString(),
),
);
To do this in initState You need WidgetsBinding.instance.addPostFrameCallback and ModalRoute.of(context).settings.arguments
Demo pass arguments: {'instalation': "123", "message": "456"}
You can see full code and working demo picture below
code snippet use push
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ExtractArgumentsScreen(),
// Pass the arguments as part of the RouteSettings. The
// ExtractArgumentScreen reads the arguments from these
// settings.
settings: RouteSettings(
arguments: {'instalation': "123", "message": "456"},
),
),
);
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
final routeArgs1 =
ModalRoute.of(context).settings.arguments as Map<String, String>;
final instalation = routeArgs1['instalation'];
final message = routeArgs1['message'];
print('instalation ${instalation}');
print('message ${message}');
key.currentState
.showSnackBar(SnackBar(content: Text(message)));
});
}
code snippet use Navigator.pushNamed
return MaterialApp(
// Provide a function to handle named routes. Use this function to
// identify the named route being pushed, and create the correct
// Screen.
routes: {
'/extractArguments': (context) => ExtractArgumentsScreen(),
},
...
Navigator.pushNamed(
context,
ExtractArgumentsScreen.routeName,
arguments: {'instalation': "123", "message": "456"},
);
working demo
full code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
// Provide a function to handle named routes. Use this function to
// identify the named route being pushed, and create the correct
// Screen.
routes: {
'/extractArguments': (context) => ExtractArgumentsScreen(),
},
onGenerateRoute: (settings) {
// If you push the PassArguments route
if (settings.name == PassArgumentsScreen.routeName) {
// Cast the arguments to the correct type: ScreenArguments.
final ScreenArguments args = settings.arguments;
// Then, extract the required data from the arguments and
// pass the data to the correct screen.
return MaterialPageRoute(
builder: (context) {
return PassArgumentsScreen(
title: args.title,
message: args.message,
);
},
);
}
},
title: 'Navigation with Arguments',
home: HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Screen'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// A button that navigates to a named route that. The named route
// extracts the arguments by itself.
RaisedButton(
child: Text("Navigate to screen that extracts arguments"),
onPressed: () {
// When the user taps the button, navigate to the specific route
// and provide the arguments as part of the RouteSettings.
Navigator.pushNamed(
context,
ExtractArgumentsScreen.routeName,
arguments: {'instalation': "123", "message": "456"},
);
/*Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ExtractArgumentsScreen(),
// Pass the arguments as part of the RouteSettings. The
// ExtractArgumentScreen reads the arguments from these
// settings.
settings: RouteSettings(
arguments: {'instalation': "123", "message": "456"},
),
),
);*/
},
),
// A button that navigates to a named route. For this route, extract
// the arguments in the onGenerateRoute function and pass them
// to the screen.
RaisedButton(
child: Text("Navigate to a named that accepts arguments"),
onPressed: () {
// When the user taps the button, navigate to a named route
// and provide the arguments as an optional parameter.
Navigator.pushNamed(
context,
PassArgumentsScreen.routeName,
arguments: ScreenArguments(
'Accept Arguments Screen',
'This message is extracted in the onGenerateRoute function.',
),
);
},
),
],
),
),
);
}
}
// A Widget that extracts the necessary arguments from the ModalRoute.
class ExtractArgumentsScreen extends StatefulWidget {
static const routeName = '/extractArguments';
#override
_ExtractArgumentsScreenState createState() => _ExtractArgumentsScreenState();
}
class _ExtractArgumentsScreenState extends State<ExtractArgumentsScreen> {
final GlobalKey<ScaffoldState> key = new GlobalKey<ScaffoldState>();
final snackBar = SnackBar(
duration: Duration(seconds: 5),
content: Text("message" + '.', textAlign: TextAlign.center),
backgroundColor: Colors.red[700],
);
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
final routeArgs1 =
ModalRoute.of(context).settings.arguments as Map<String, String>;
final instalation = routeArgs1['instalation'];
final message = routeArgs1['message'];
print('instalation ${instalation}');
print('message ${message}');
key.currentState
.showSnackBar(SnackBar(content: Text(message)));
});
}
#override
void didChangeDependencies() {
super.didChangeDependencies();
}
#override
Widget build(BuildContext context) {
// Extract the arguments from the current ModalRoute settings and cast
// them as ScreenArguments.
final routeArgs =
ModalRoute.of(context).settings.arguments as Map<String, String>;
final instalation = routeArgs['instalation'];
final message = routeArgs['message'];
return Scaffold(
key: key,
appBar: AppBar(
title: Text(' ${routeArgs['code']} '),
),
body: Column(
children: <Widget>[
Center(
child: Text('instalation ${instalation}'),
),
RaisedButton(
onPressed: () {
key.currentState.showSnackBar(snackBar);
},
),
],
),
);
}
}
// A Widget that accepts the necessary arguments via the constructor.
class PassArgumentsScreen extends StatelessWidget {
static const routeName = '/passArguments';
final String title;
final String message;
// This Widget accepts the arguments as constructor parameters. It does not
// extract the arguments from the ModalRoute.
//
// The arguments are extracted by the onGenerateRoute function provided to the
// MaterialApp widget.
const PassArgumentsScreen({
Key key,
#required this.title,
#required this.message,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Text(message),
),
);
}
}
// You can pass any object to the arguments parameter. In this example,
// create a class that contains both a customizable title and message.
class ScreenArguments {
final String title;
final String message;
ScreenArguments(this.title, this.message);
}
So, I see you're using the simple routes approach.
In order to extract route arguments you need to supply an onGenerateRoute function to your MaterialApp (or Cupertino, I guess).
You can find an exhaustive example on how to do it here, so I won't crowd this answer more than that.
Hope this solves your problem, happy coding!