This is my code what i am doing it that on tap i need to go to another page ,but i am getting an error Navigator operation requested with a context that does not include a Navigator.
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
final title = 'SHA-WAY';
var FirstPage = ['SURGERIES','OPERTAION THEATER TECHNICIAN','DRESSINGS OR BANDAGES','PHYSIOTHERAPY','NURSE MALE|FEMALE',
'HOSPITAL LINEN OR STAFF UNIFORM','MEDICENS(ONLY RARE INJECTIONS)','OPERATION THEATRE INSTRUMENTS|EQUIPEMENTS'];
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Container(
child: GridView.count(
// Create a grid with 2 columns. If you change the scrollDirection to
// horizontal, this produces 2 rows.
crossAxisCount: 2,
children: [
Card(
child: InkWell(
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => surgeries()),
);
},
splashColor: Colors.blue,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(Icons.content_cut,size: 60.0,),
Text(FirstPage[0]),
],
)
),
),
),
This is the class where i want to navigate,
import 'package:flutter/material.dart';
class surgeries extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("SURGERIES"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
don't know what i am doing wrong just started FLUTTER and i am stuck
You can use the approach shown in the official doc,
You have to define the routes in the main.dart
MaterialApp(
// Start the app with the "/" named route. In this case, the app starts
// on the FirstScreen widget.
initialRoute: '/',
routes: {
// When navigating to the "/" route, build the FirstScreen widget.
'/': (context) => FirstScreen(),
// When navigating to the "/second" route, build the SecondScreen widget.
'/second': (context) => SecondScreen(),
},
);
Then you can navigate to the First screen to another on onTap or onPressed event like this,
Navigator.pushNamed(context, '/second');
Note: You should only have one MaterialApp in your whole app.
For more head over to official Page
Your all classes should be descendant of MaterialApp widget, to achieve that, wrap your class that placed on runApp method with MaterialApp widget, then remove all of other MaterialApp widgets from your widget tree.
void main() {
runApp(MaterialApp(home:MyApp));
}
Just tried this and work!
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'example',
debugShowCheckedModeBanner: false,
theme: 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 simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
buttonTheme: ButtonThemeData(
buttonColor: Colors.blue,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
textTheme: ButtonTextTheme.primary
)
),
home: Esempio1()
);
}
}
class Esempio1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("WAKAWAKA"),
),
body: Container(
child: Column(
children: <Widget>[
RaisedButton(
child: Text("aasdasd"),
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (_)=> Esempio2()));
},
)
],
),
),
);
}
}
class Esempio2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("eheh"),
),
body: Container(
child: Text("AAAAA"),
),
);
}
}
Related
I have a MaterialApp in my main.dart within a Nav() Widget which contains a Scaffold with an appBar and a BottomNavigationBar. The NavigationBar has 4 BottomNavigationBarItems, but I have more Pages than 4 in my whole App. The other pages can be accessed via the first BottomNavigationBarItem 'Home'. But when I push the new NamedRoute the AppBar disapears. How can I solve this Problem?
I've already tried using the bottomNavigationBar in my own Widget in a new File. Problem: setState() doesn't work.
Here's some code
main.dart:
import 'package:flutter/material.dart';
import 'pages/nav.dart';
import 'route/route.dart' as route;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Lieferantenapp',
theme: 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 simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.red,
),
home: Nav(),
onGenerateRoute: route.controller,
//initialRoute: route.navPage,
);
}
}
nav.dart
import 'package:flutter/material.dart';
import 'package:lieferantenapp/components/MyAppBar.dart';
import 'package:lieferantenapp/components/MyThreeLineText.dart';
//import 'package:lieferantenapp/components/myBottomNavigationBar.dart';
import 'package:lieferantenapp/components/myCard.dart';
import 'package:lieferantenapp/pages/bestellungen.dart';
import 'package:lieferantenapp/pages/packliste.dart';
import 'package:lieferantenapp/pages/tour.dart';
import 'package:lieferantenapp/pages/home.dart';
class Nav extends StatefulWidget {
#override
_NavState createState() => _NavState();
}
class _NavState extends State<Nav> {
int _selectedIndex = 0;
List<Widget> _widgetOptions = <Widget>[
Home(),
Tour(),
Bestellungen(),
Packliste(),
];
void _onItemTap(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
//Custom App Bar without any passed data
appBar: myAppBar(context, null, null),
backgroundColor: Colors.white,
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
type: BottomNavigationBarType.fixed,
fixedColor: Colors.red,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(
icon: Icon(Icons.local_shipping),
label: 'Tour',
),
BottomNavigationBarItem(
icon: Icon(Icons.inventory_2),
label: 'Packliste',
),
BottomNavigationBarItem(
icon: Icon(Icons.receipt_long),
label: 'Bestellungen',
),
],
onTap: _onItemTap,
),
body: _widgetOptions.elementAt(_selectedIndex),
);
}
}
home.dart:
import 'package:flutter/material.dart';
import 'package:lieferantenapp/components/MyThreeLineText.dart';
import 'package:lieferantenapp/components/myCard.dart';
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(
children: [
//BlackBoard Message
//TODO get BlackBoard Message from Server
//myThreeLineText(Context, TextTheme, OVerline, Title, Body)
myThreeLineText(
context,
Theme.of(context).textTheme,
'12.07.2021',
'Servus und Mahlzeit!',
"Herzlich Willkommen in der neuen Mahlzeit LieferApp mit " +
"optimierter Routenplanung via Google Maps.",
),
Expanded(
child: GridView.count(
shrinkWrap: true,
primary: false,
padding: const EdgeInsets.all(18),
crossAxisSpacing: 15,
mainAxisSpacing: 15,
crossAxisCount: 2,
children: <Widget>[
myCard(
context,
Icons.map_outlined,
'Touren',
Theme.of(context).textTheme,
Color(0xff119052),
),
myCard(
context,
Icons.local_shipping_outlined,
'Touren',
Theme.of(context).textTheme,
Color(0xffFF9444),
),
myCard(
context,
Icons.inventory_2_outlined,
'Touren',
Theme.of(context).textTheme,
Color(0xff84000F),
),
myCard(
context,
Icons.receipt_long_outlined,
'Touren',
Theme.of(context).textTheme,
Color(0xffCB5E5E),
),
myCard(
context,
Icons.bookmark_border_outlined,
'Touren',
Theme.of(context).textTheme,
Color(0xffCC3021),
),
myCard(
context,
Icons.settings_outlined,
'Touren',
Theme.of(context).textTheme,
Color(0xff57BB61),
),
],
),
),
],
);
}
}
myCard.dart:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:lieferantenapp/route/route.dart' as route;
Widget myCard(BuildContext context, IconData icon, String text, TextTheme theme,
Color cColor) {
return GestureDetector(
//TODO implement ROUTE ontap start Cards
onTap: () => {},
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
icon,
color: Colors.white,
size: 30,
),
SizedBox(height: 25),
Text(
text,
style: theme.bodyText1.apply(color: Colors.white),
),
],
),
color: cColor,
),
);
}
I am also open for Tips and Tricks to improve my code.
EDIT - new main.dart:
import 'package:flutter/material.dart';
import 'package:lieferantenapp/components/MyAppBar.dart';
import 'pages/nav.dart';
import 'route/route.dart' as route;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Mahlzeit Lieferantenapp',
theme: ThemeData(
primarySwatch: Colors.red,
),
//home: Nav(),
//onGenerateRoute: route.controller,
builder: (context, _) => Scaffold(
appBar: myAppBar(context, null, null),
body: Navigator(onGenerateRoute: route.controller),
),
//initialRoute: route.navPage,
);
}
}
The app bar is part of the Scaffold which will appear only on the 4 widgets In _widgetOptions. If you don't have that Scaffold on your page there is no app bar.
Wrapping your Navigator with your Scaffold (i.e. Scaffold on TOP of the Navigator) should do the trick.
Note that when you're 'returning' a Widget from a build function it becomes a child. When you are using Navigator to push a Widget it becomes a sibling and will be on top of the current screen. You can visualize this clearly in the dev tools.
EDIT: Since you're using the default MaterialApp's Navigator this won't work. You will need to create your own Navigator for this.
i.e: Remove home parameter from MaterialApp. Use builder parameter instead. And provide a Navigator widget to the builder (wrapped by your Scaffold)
Something like this:
MaterialApp(builder: (context, _) => Scaffold( ....., body: Navigator( onGenerateRoutes:...)))
I am trying to make navigation by serving pages via BLoC (flutter_bloc 6.1.1).
main.dart:
class MyApp extends StatelessWidget {
List<MaterialPage> _pages = [
MaterialPage( key: ValueKey('Page1'), child: Page1() ),
];
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: BlocProvider(
create: (BuildContext context) => NavCubit(),
// WHY PAGES NOT UPDATES HERE FROM BLoC?????
child: BlocListener<NavCubit, NavState>(
listener: (context, state) {
_pages = state.pages;
},
child: Navigator(
pages: _pages,
onPopPage: (route, result) {
if ( !route.didPop(result) ) {
return false;
}
return true;
},
)
)
),
);
}
}
The first page (Page 1) has a button, clicking on which should navigate to the second page (Page2)
class Page1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => NavCubit(),
child: Scaffold(
appBar: AppBar( title: Text('Page 1') ),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("page 11111111111"),
RaisedButton(
child: Text('Go to: Page 2', style: TextStyle(fontSize: 20)),
onPressed: () {
print("goto page2 btn");
context.read<NavCubit>().navigateTo();
},
),
],
)
),
),
);
}
}
class NavCubit extends Cubit<NavState> {
...
void navigateTo() {
final navState = NavState([MaterialPage( key: ValueKey('Page2'), child: Page2() )]);
debugPrint(navState.toString());
emit(navState);
}
}
But it doesn't happen!
As far as I can see, the BLoC State are updated good. But no screen changes...
SEE PLS:
Here my full test project: https://github.com/morfair/flutter_test_app/tree/master/lib
In Page1 you are creating another NavCubit in the BlocProvider. Therefore you have 2 NavCubits in total. So when you then call context.read<NavCubit>.navigateTo(), you are calling this method on the wrong NavCubit. Try to remove the creation of a second cubit in the BlocProvider in the Page1 build method.
I have a MaterialApp in which it has an IndexedStack as its homePage, to use it for BottomBarNavigation. Now, in one of the "Tab"s, I want page transitions to be done like it is done in iOS.
Part of the trick can be done using CupertinoPageRoute in Navigator.push as follows:
Navigator.of(context, rootNavigator: true).push(CupertinoPageRoute<bool>(
//fullscreenDialog: true,
builder: (BuildContext context) => new DescriptionPage(),
));
this results the new page to slide from right as an iOS app. But, I also want the first page to be shifted to right with parallax, as it says in the CupertinoPageRoute's documentation:
The page also shifts to the left in parallax when another page enters to cover it.
this will be done if the first page itself is created via "Navigator.push(CupertinoPageRoute ...", but as I mentioned, my first page is one of the main pages of the application's home.
current transition style:
the new page slides in from right, but the current page does not shift to left
as you can see, the current page does not shift to left. There might be a way to make the current page's widget to act as a widget built by a CupertinoPageRoute, so that the current page itself slides to left as the new page comes in.
In the theme: parameter of MaterialApp, try this:
MaterialApp(
theme: ThemeData( //or replace with your custom ThemeData.copywith()
pageTransitionsTheme: PageTransitionsTheme(
builders: {
TargetPlatform.android: CupertinoPageTransitionsBuilder(),
TargetPlatform.iOS: CupertinoPageTransitionsBuilder()
}
),
),
)
If you run the code below, you will see that First Tab is doing what you are seeing and second Tab is what you are expecting.
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: CupertinoStoreHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class CupertinoStoreHomePage extends StatelessWidget {
const CupertinoStoreHomePage({title});
#override
Widget build(BuildContext context) {
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.bell),
title: Text('TAB1'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.bell_solid),
title: Text('TAB2'),
),
],
),
tabBuilder: (context, index) {
switch (index) {
case 0:
return CupertinoTabView(builder: (context) {
return CupertinoPageScaffold(
child: TAB1(),
);
});
case 1:
return CupertinoTabView(
builder: (context) {
return CupertinoPageScaffold(
child: TAB2(),
);
},
routes: {
'/screen': (ctx) => NextScreen(),
},
);
default:
return Container();
}
},
);
}
}
class TAB1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("TAB1"),
),
body: Container(
child: FlatButton(
child: Text("Go To Next Screen"),
onPressed: () => Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => NextScreen())),
),
),
);
}
}
class TAB2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("TAB2"),
),
body: Container(
child: FlatButton(
child: Text("Go To Next Screen"),
onPressed: () => Navigator.of(context).pushNamed("/screen"),
)),
);
}
}
class NextScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Scaffold(
appBar: AppBar(
title: Text("NextScreen"),
),
body: Container(
child: Text("NextScreen"),
),
),
);
}
}
When using Navigator.of(ctx).push the app tries to push new screen on root navigator, which in your case is tab bar but it fails to replace the tab bar, hence you see incomplete animation. But with second approach where you have defined route in relevant tab and use Push Named, the app uses navigator assigned to that tab and hence expected result.
Happy Coding!
i am trying to go on another page using navigation, but i am getting error;
Navigator operation requested with a context that does not include a
Navigator.
i am just trying to move on next page, i followed flutter documentations for this stateless widget but how to do with state full widget.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
State createState() => new MyApp1();
}
class MyApp1 extends State<MyApp> {
List<Widget> _listSection = [];
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Share IDEASS',
initialRoute: '/',
routes: {
'/second': (context) => SecondScreen(),
},
home: Scaffold(
appBar: AppBar(
title: Text('IDEAS'),
),
body: Container(
child: Stack(
children: [
floatingButton(),
],
),
),
),
);
}
Widget floatingButton() {
return Container(
padding: const EdgeInsets.all(30),
alignment: Alignment.bottomRight,
child: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, "/SecondScreen");
},
child: Text("+"),
backgroundColor: Colors.blue,
),
);
}
}
class SecondScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
You should use the named route you created.
Widget floatingButton(BuildContext context) { // added context as a parameter
return Container(
padding: const EdgeInsets.all(30),
alignment: Alignment.bottomRight,
child: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, "/second"); // Changed this to use the named route
},
child: Text("+"),
backgroundColor: Colors.blue,
),
);
}
}
then use the following
body: Container(
child: Stack(
children: [
floatingButton(context),
],
),
),
The situation here is that the floatingButton() uses a context with the navigator to push the given page route. But the context used is provided in the parent Widget(MaterialApp) it self, which doesn't include a Navigator, hence the error.
So, Try this approach:
Separate the Home widget from the MaterialApp, like below:
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Share IDEASS',
initialRoute: '/',
routes: {
'/second': (context) => SecondScreen(),
},
home: HomePage(),
);
Create a stateless widget containing the Scaffold:
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('IDEAS'),
),
body: Container(
child: Stack(
children: [
floatingButton(),
],
),
),
);
}
}
Hope it helps. Let me know if this doesn't work.
You have made two mistakes because of which your code is not working:
You have used wrong route name. Replace /SecondScreen with /second
You have used wrong context. You can get Navigator only if your widget has MaterialApp as it's parent and here you are using context of MyApp1 so it is not working.
Following is a working code for your reference.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
State createState() => new MyApp1();
}
class MyApp1 extends State<MyApp> {
List<Widget> _listSection = [];
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Share IDEASS',
initialRoute: '/',
routes: {
'/second': (context) => SecondScreen(),
},
home: AppContent(),
);
}
}
class AppContent extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('IDEAS'),
),
body: Container(
child: Stack(
children: [
floatingButton(context),
],
),
),
);
}
Widget floatingButton(BuildContext context) {
return Container(
padding: const EdgeInsets.all(30),
alignment: Alignment.bottomRight,
child: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, "/second");
},
child: Text("+"),
backgroundColor: Colors.blue,
),
);
}
}
class SecondScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
In my Flutter project, I have three screens - Screen0, Screen1, Screen2. Now, from the screen0 , I can go to the screen1 with a button click, then from screen1 we can go to screen2 with a button. In screen2, I have a button which I have used to go back to screen0. As Screen0 is the initial screen, I want to clear all the previous screens when I come back to Screen0 and don't want to have any back option like in this image-
And here's my code-
main.dart
import 'package:flutter/material.dart';
import 'screen0.dart';
import 'screen1.dart';
import 'screen2.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context)=> Screen0(),
'/first': (context)=> Screen1(),
'/second': (context)=> Screen2(),
},
);
}
}
I have set all the routes in my main.dart file. Then in the Screen0, I have a button to go to screen1 like below-
screen0.dart
import 'package:flutter/material.dart';
class Screen0 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.purple,
title: Text('Screen 0'),
),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
color: Colors.red,
child: Text('Go to screen 1'),
onPressed: (){
Navigator.pushNamed(context, '/first');
},
),
],
),
),
);
}
}
In the screen1, I have a button to go to screen2-
class Screen1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.purple,
title: Text('Screen 1'),
),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
color: Colors.red,
child: Text('Go to screen 2'),
onPressed: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return Screen2();
})
);
},
),
],
),
),
);
}
}
Now, in the screen2, i have the button to go to screen0 -
class Screen2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.purple,
title: Text('Screen 2'),
),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
color: Colors.red,
child: Text('Go to screen 0'),
onPressed: (){
Navigator.pop(context, Screen2);
Navigator.pushNamed(context, '/');
},
),
],
),
),
);
}
}
I have tried some solution like using Navigator.pushAndRemoveUntil given in the below link-
Flutter - Navigate to a new screen, and clear all the previous screens
But this solution didn't work for me.
So, it would be nice if someone help me out this code to solve the problem.
use pushNamedAndRemoveUntil
for example
Navigator.of(context).pushNamedAndRemoveUntil('/screen4', (Route<dynamic> route) => false);