flutter localization error when set title - flutter

localizaed.dart
import 'package:flutter/cupertino.dart';
class Localized {
Localized(this.locale);
final Locale locale;
static Localized of(BuildContext context) => Localizations.of<Localized>(context, Localized);
static Map<String, Map<String,String>> _v = {
'en': {
'title': 'hello world',
},
'ja': {
'title': 'こんちは'
}
};
String get title => _v[locale.languageCode]['title'];
}
class LocalizedDelagate extends LocalizationsDelegate<Localized> {
const LocalizedDelagate();
#override
bool isSupported(Locale locale) => ['en','ja'].contains(locale.languageCode);
#override
Future<Localized> load(Locale locale) async => Localized(locale);
#override
bool shouldReload(LocalizationsDelegate old) => false;
}
main.dart
import 'package:calculator/src/localization/localized.dart';
import 'package:flutter/material.dart';
import 'package:calculator/src/pages/HomePage.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
void main() => runApp(StockCalcApp());
class StockCalcApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: [
const LocalizedDelagate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate
],
supportedLocales: [
const Locale('en'),
const Locale('ja'),
],
onGenerateTitle: (BuildContext context) => Localized.of(context).title, // notthing problem
theme: ThemeData(primarySwatch: Colors.pink),
home: Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(
title: Text(Localized.of(context).title), // and same code but, error. when I comment this line then, nothing well.
backgroundColor: Colors.pink[900],
elevation: 0.0,
),
body: StockHome(),
),
);
}
}
I cannot understand why to occur an error this message on the screen.
NoSuchMethodError: The getter 'title' was called on null.
I just do this example find on the web. and I think.. is very simple .. I think.
but seriously I cannot understand why to bring up this message on the android emulator.

When you call onGenerateTitle: (BuildContext context) => Localized.of(context).title, it uses a new BuildContext, which already contains the LocalizedDelagate(), so it can be called with Localized.of(context).
When you use it within the same build method, you refer to an instance of context before the LocalizedDelagate() was created, so Localized.of(context) doesn't return anything.
You can avoid this problem by creating a new Widget, which will have an updated BuildContext in it's build method, that will have access to Localized.
For example, create a new widget named HomeScreen
class StockCalcApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: [
const LocalizedDelagate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate
],
supportedLocales: [
const Locale('en'),
const Locale('ja'),
],
onGenerateTitle: (BuildContext context) => Localized.of(context).title,
theme: ThemeData(primarySwatch: Colors.pink),
home: HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(
title: Text(Localized.of(context).title), // this context will have access to Localized
backgroundColor: Colors.pink[900],
elevation: 0.0,
),
body: StockHome(),
);
}
}

Related

Flutter Provider.of<> without a consumer don't change my state

I am trying to get into the provider topic, however calling a function only works if I put it into a consumer
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ClickerProvider()),
],
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Text("some text"),
),
floatingActionButton: FloatingActionButton(
onPressed: () => Provider.of<ClickerProvider>(context, listen: false)
.incrementCounter(),
tooltip: 'Increment',
child: Icon(Icons.add),
),
));
}
As in this example, my state is not updated. However, it already works with a consumer.
floatingActionButton: Consumer<ClickerProvider>(
builder: (context, value, child) {
return FloatingActionButton(
onPressed: Provider.of<ClickerProvider>(context, listen: false)
.incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
);
},
)
Is there an error in my code?
You can copy paste run two full code below
Reason : Can not find ClickerProvider
Solution 1: Move ClickerProvider to upper level such as MyApp
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ClickerProvider()),
],
child: MaterialApp(
Solution 2: Use Builder
body: Center(child: Builder(builder: (BuildContext context) {
return Text(context.watch<ClickerProvider>().getCounter.toString());
})),
floatingActionButton: Builder(builder: (BuildContext context) {
return FloatingActionButton(
onPressed: () =>
Provider.of<ClickerProvider>(context, listen: false)
.incrementCounter(),
tooltip: 'Increment',
child: Icon(Icons.add),
);
full code 1
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ClickerProvider extends ChangeNotifier {
int _count = 0;
int get getCounter {
return _count;
}
void incrementCounter() {
_count += 1;
notifyListeners();
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ClickerProvider()),
],
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
));
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Text(context.watch<ClickerProvider>().getCounter.toString()),
),
floatingActionButton: FloatingActionButton(
onPressed: () => Provider.of<ClickerProvider>(context, listen: false)
.incrementCounter(),
tooltip: 'Increment',
child: Icon(Icons.add),
));
}
}
full code 2
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ClickerProvider extends ChangeNotifier {
int _count = 0;
int get getCounter {
return _count;
}
void incrementCounter() {
_count += 1;
notifyListeners();
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ClickerProvider()),
],
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(child: Builder(builder: (BuildContext context) {
return Text(context.watch<ClickerProvider>().getCounter.toString());
})),
floatingActionButton: Builder(builder: (BuildContext context) {
return FloatingActionButton(
onPressed: () =>
Provider.of<ClickerProvider>(context, listen: false)
.incrementCounter(),
tooltip: 'Increment',
child: Icon(Icons.add),
);
}),
));
}
}
As you can refer in the source code of Consumer here:
Obtains [Provider] from its ancestors and passes its value to [builder].
The [Consumer] widget doesn't do any fancy work. It just calls [Provider.of]
in a new widget, and delegates its build implementation to [builder].
Provider.of<X> depends on value of listen (true or false) to trigger new State.build() to widgets and State.didChangeDependencies() for StatefulWidget.
Consumer<X> always update UI, as it uses Provider.of<T>(context), where listen is true
In this case, since your listen is set as false, but you're putting it in the Consumer which make it true. That's why the UI will update with Consumer

How do I pass the data from the checked List Tile to the next page (Basket) in flutter

I previously used a Listview to present my data, but I was advised to use a Checkbox List tile now I'm stuck on how to pass data. I want to pass the selected/checked List tile's data to the next page (Basket). How do I do that, please help me.
I am new to Flutter.
The Main Method Class
import 'package:cart_app1/Basket.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(),
initialRoute: '/',
routes: {
'/': (context) => MyHomePage(),
Basket.routeName: (context) => Basket(),
},
);
}
}
The product list class
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Map<String, bool> values = {
"GIN COCKTAILS \nClover Club \t R65": false,
"Beers & Ciders \nHeineken NRB \t R29": false,
"Vodka \nCiroc \t R35": false,
"Vodka \nCruz Vodka \t R30": false,
"COGNAC \nHennesy \t R40": false,
"Tequilla \nEl Jimador \t R30": false,
"Non-Alcoholic \nSoft-Drink \t R20": false,
"WHISK[E]Y \nJohnie Walker Red \t R25": false,
};
var toggle = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("The Wing Republic"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.shopping_basket),
onPressed: () {
Navigator.of(context)
.pushNamed(Basket.routeName, arguments: values);
},
),
],
),
body: ListView(
children: values.keys.map((String key) {
return CheckboxListTile(
title: Text(key),
subtitle: Text(""),
isThreeLine: false,
value: values[key],
onChanged: (bool value) {
setState(() {
values[key] = value;
});
},
);
}).toList(),
),
);
}
}
The Basket Method
import 'package:flutter/material.dart';
class Basket extends StatelessWidget {
static const routeName = '/Basket';
#override
Widget build(BuildContext context) {
final data = ModalRoute.of(context).settings.arguments as Map<String, bool>;
return Scaffold();
}
}
You can pass arguments in pushNamed method.
Navigator.of(context).pushNamed(Basket.routeName, arguments: values);
On the receiving end, use ModalRoute to get the values.
import 'package:flutter/material.dart';
class Basket extends StatelessWidget {
static const routeName = '/Basket';
#override
Widget build(BuildContext context) {
final data = ModalRoute.of(context).settings.arguments as Map<String, bool>;
return Scaffold();
}
}
Routes in MyApp is incorrect. If you want to use routes, you can't use home property. Instead of home specify initialRoute.
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
visualDensity: VisualDensity.adaptivePlatformDensity,
),
initialRoute: '/',
routes: {
'/': (context) => MyHomePage(),
Basket.routeName: (context) => Basket(),
},
);
}
}

How to change appBar's back icon theme globally?

Flutter automatically provides a back button for routes that can pop, but how can I change the back button Icon theme through the whole app?
Like how can I change the normal material back icon to chevron?
Create pages without Scafold and use this method to navigate between routes.
navigateToRoute(BuildContext context, Widget page,String title) {
Navigator.push(context, MaterialPageRoute(builder: (context) => Scaffold(
appBar: AppBar(
leading:Icon(Icons.chevron_left),
title: Text(title),
),
body: page,
)));
}
You have to create a custom BackButton in that case. I'll suggest that you can create a customAppBar method and use it everywhere.
Checkout the below code.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ScreenOne(),
);
}
}
class ScreenOne extends StatefulWidget {
#override
_ScreenOneState createState() => _ScreenOneState();
}
class _ScreenOneState extends State<ScreenOne> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: customAppBar(title: Text("Screen One")),
body: Center(
child: RaisedButton(onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => ScreenTwo()));
}),
),
);
}
}
class ScreenTwo extends StatefulWidget {
#override
_ScreenTwoState createState() => _ScreenTwoState();
}
class _ScreenTwoState extends State<ScreenTwo> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: customAppBar(
customBackButton: true,
title: Text("Screen Two"),
),
);
}
}
AppBar customAppBar({
Widget title,
bool customBackButton = false,
}) {
return AppBar(
leading: customBackButton ? CustomBackButton() : null,
title: title,
);
}
class CustomBackButton extends StatelessWidget {
const CustomBackButton({Key key, this.color, this.onPressed}) : super(key: key);
final Color color;
final Function onPressed;
#override
Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context));
return IconButton(
icon: Icon(Icons.arrow_back_ios),
color: color,
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
onPressed: () {
if (onPressed != null) {
onPressed();
} else {
Navigator.maybePop(context);
}
},
);
}
}
Hope it helps :)
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
appBarTheme: AppBarTheme(
iconTheme: IconThemeData(
color: Colors.black,
),
),
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);[![Initially didn't put any color so it was white[![This is the image when I added appbartheme and changed color to black][1]][1]][1]

Consumer of ChangeNotifierProvider is always null

The Machinemodel instance from the Consumer is always null.
Why?
App
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Provider nested model demo',
theme: ThemeData(
// This is the theme of your application.
primarySwatch: Colors.blue,
),
home: ApplicationPage());
}
}
ApplicationPage
class ApplicationPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
var newMachineEntity = new MachineEntity(1, "Power x1000"); //, engines);
return Scaffold(
appBar: AppBar(title: Text("Machine demo"), elevation: 6),
body: ChangeNotifierProvider(create: (context) => new MachineModel(newMachineEntity), child: MachineWidget()));
}
}
Widget
class MachineWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Consumer<MachineModel>(builder: (context, machine, child) {
////////////////////// machine instance is null /////////////
return Container(
child: Column(
children: <Widget>[
TextFormField(
initialValue: machine.name,
onChanged: (value) => machine.name = value,
),
],
),
);
});
}
}
Model
class MachineModel extends ChangeNotifier {
MachineEntity machineEntity;
// List<EngineModel> engines;
MachineModel(this.machineEntity) {
// engines = this.machineEntity.engines.map((eng) => new EngineModel(eng)).toList();
}
String get name => machineEntity.name;
set name(String value) {
machineEntity.name = value;
notifyListeners();
}
}
Entity
class MachineEntity {
int id;
String name;
// List<EngineEntity> engines;
MachineEntity(this.id, this.name); //, this.engines);
}

Navigator operation requested with a context that does not include a Navigator

I'm trying to start a new screen within an onTap but I get the following error:
Navigator operation requested with a context that does not include a
Navigator.
The code I am using to navigate is:
onTap: () { Navigator.of(context).pushNamed('/settings'); },
I have set up a route in my app as follows:
routes: <String, WidgetBuilder>{
'/settings': (BuildContext context) => new SettingsPage(),
},
I've tried to copy the code using the stocks sample application. I've looked at the Navigator and Route documentation and can't figure out how the context can be made to include a Navigator. The context being used in the onTap is referenced from the parameter passed into the build method:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
SettingsPage is a class as follows:
class SettingsPage extends Navigator {
Widget buildAppBar(BuildContext context) {
return new AppBar(
title: const Text('Settings')
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: buildAppBar(context),
);
}
}
TLDR: Wrap the widget which needs to access to Navigator into a Builder or extract that sub-tree into a class. And use the new BuildContext to access Navigator.
This error is unrelated to the destination. It happens because you used a context that doesn't contain a Navigator instance as parent.
How do I create a Navigator instance then ?
This is usually done by inserting in your widget tree a MaterialApp or WidgetsApp. Although you can do it manually by using Navigator directly but less recommended. Then, all children of such widget can access NavigatorState using Navigator.of(context).
Wait, I already have a MaterialApp/WidgetsApp !
That's most likely the case. But this error can still happens when you use a context that is a parent of MaterialApp/WidgetsApp.
This happens because when you do Navigator.of(context), it will start from the widget associated to the context used. And then go upward in the widget tree until it either find a Navigator or there's no more widget.
In the first case, everything is fine. In the second, it throws a
Navigator operation requested with a context that does not include a Navigator.
So, how do I fix it ?
First, let's reproduce this error :
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Center(
child: RaisedButton(
child: Text("Foo"),
onPressed: () => Navigator.pushNamed(context, "/"),
),
),
);
}
}
This example creates a button that attempts to go to '/' on click but will instead throw an exception.
Notice here that in the
onPressed: () => Navigator.pushNamed(context, "/"),
we used context passed by to build of MyApp.
The problem is, MyApp is actually a parent of MaterialApp. As it's the widget who instantiate MaterialApp! Therefore MyApp's BuildContext doesn't have a MaterialApp as parent!
To solve this problem, we need to use a different context.
In this situation, the easiest solution is to introduce a new widget as child of MaterialApp. And then use that widget's context to do the Navigator call.
There are a few ways to achieve this. You can extract home into a custom class :
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHome()
);
}
}
class MyHome extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: Text("Foo"),
onPressed: () => Navigator.pushNamed(context, "/"),
),
);
}
}
Or you can use Builder :
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Builder(
builder: (context) => Center(
child: RaisedButton(
child: Text("Foo"),
onPressed: () => Navigator.pushNamed(context, "/"),
),
),
),
);
}
}
Hy guys, i have the same problem. This is occur for me. The solution what i found is very simple. Only what i did is in a simple code:
void main() {
runApp(MaterialApp(
home: YOURAPP() ,
),
);
}
I hope was useful.
Make sure your current parent widget not with same level with MaterialApp
Wrong Way
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Title'),
),
body: Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: RaisedButton(
onPressed: () {
//wrong way: use context in same level tree with MaterialApp
Navigator.push(context,
MaterialPageRoute(builder: (context) => ScanScreen()));
},
child: const Text('SCAN')),
)),
),
);
}
}
Right way
void main() => runApp(MaterialApp(
title: "App",
home: HomeScreen(),
));
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Title'),
),
body: Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: RaisedButton(
onPressed: () {
//right way: use context in below level tree with MaterialApp
Navigator.push(context,
MaterialPageRoute(builder: (context) => ScanScreen()));
},
child: const Text('SCAN')),
)),
);
}
}
Just like with a Scaffold you can use a GlobalKey. It doesn't need context.
final _navKey = GlobalKey<NavigatorState>();
void _navigateToLogin() {
_navKey.currentState.popUntil((r) => r.isFirst);
_navKey.currentState.pushReplacementNamed(LoginRoute.name);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: _navKey,
...
);
}
I set up this simple example for routing in a flutter app:
import 'package:flutter/material.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(),
routes: <String, WidgetBuilder>{
'/settings': (BuildContext context) => new SettingsPage(),
},
);
}
}
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('TestProject'),
),
body: new Center(
child: new FlatButton(
child: const Text('Go to Settings'),
onPressed: () => Navigator.of(context).pushNamed('/settings')
)
)
);
}
}
class SettingsPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('SettingsPage'),
),
body: new Center(
child: new Text('Settings')
)
);
}
}
Note, that the SettingsPage extends StatelessWidget and not Navigator. I'm not able to reproduce your error.
Does this example help you in building your app? Let me know if I can help you with anything else.
You should rewrite your code in main.dart
FROM:
void main() => runApp(MyApp());
TO
void main() {
runApp(MaterialApp(
title: 'Your title',
home: MyApp(),));}
The point is to have the home property to be your first page
this worked for me, I hope it will help someone in the future
A complete and tested solution:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:my-app/view/main-view.dart';
class SplashView extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: Builder(
builder: (context) => new _SplashContent(),
),
routes: <String, WidgetBuilder>{
'/main': (BuildContext context) => new MainView()}
);
}
}
class _SplashContent extends StatefulWidget{
#override
_SplashContentState createState() => new _SplashContentState();
}
class _SplashContentState extends State<_SplashContent>
with SingleTickerProviderStateMixin {
var _iconAnimationController;
var _iconAnimation;
startTimeout() async {
var duration = const Duration(seconds: 3);
return new Timer(duration, handleTimeout);
}
void handleTimeout() {
Navigator.pushReplacementNamed(context, "/main");
}
#override
void initState() {
super.initState();
_iconAnimationController = new AnimationController(
vsync: this, duration: new Duration(milliseconds: 2000));
_iconAnimation = new CurvedAnimation(
parent: _iconAnimationController, curve: Curves.easeIn);
_iconAnimation.addListener(() => this.setState(() {}));
_iconAnimationController.forward();
startTimeout();
}
#override
Widget build(BuildContext context) {
return new Center(
child: new Image(
image: new AssetImage("images/logo.png"),
width: _iconAnimation.value * 100,
height: _iconAnimation.value * 100,
)
);
}
}
As per this comment If your navigator is inside Material context navigator push will give this error. if you create a new widget and assign it to the material app home navigator will work.
This won't work
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text("Title"),
),
body: new Center(child: new Text("Click Me")),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.add),
backgroundColor: Colors.orange,
onPressed: () {
print("Clicked");
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new AddTaskScreen()),
);
},
),
),
);
}
}
This will work
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new HomeScreen());
}
}
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Title"),
),
body: new Center(child: new Text("Click Me")),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.add),
backgroundColor: Colors.orange,
onPressed: () {
print("Clicked");
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new AddTaskScreen()),
);
},
),
);
}
}
I was facing the same problem and solved by removing home from MaterialApp and use initialRoute instead.
return MaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: '/',
routes: {
'/': (context) => MyApp(),
'/settings': (context) => SettingsPage(),
},
);
And
onTap: () => {
Navigator.pushNamed(context, "/settings")
},
It is Simple
instead using this normal code
`runApp(BasicBankingSystem());`
wrap it with MaterialApp
runApp(MaterialApp(home: BasicBankingSystem()));
It happens because the context on the widget that tries to navigate is still using the material widget.
The short answer for the solution is to :
extract your widget
that has navigation to new class so it has a different context when calling the navigation
When your screen is not navigated from other screen,you don't initially have access to the navigator,Because it is not instantiated yet.So in that case wrap your widget with builder and extract context from there.This worked for me.
builder: (context) => Center(
child: RaisedButton(
child: Text("Foo"),
onPressed: () => Navigator.pushNamed(context, "/"),
),
You ca use this plugin
https://pub.dev/packages/get/versions/2.0.2
in The MaterialApp assign property navigatorKey: Get.key,
MaterialApp(
navigatorKey: Get.key,
initialRoute: "/",
);
you can access Get.toNamed("Your route name");
Change your main function example:
void main() {
runApp(
MaterialApp(
title: 'Your title',
home: MyApp(),
)
);
}
use this
void main() {
runApp(MaterialApp(debugShowCheckedModeBanner: false, home: MyApp()),);
}
instead of this
void main() {runApp(MyApp());}
Wrap with materialapp
reproduce code
import 'dart:convert';
import 'package:flutter/material.dart';
void main() {
// reproduce code
runApp(MyApp());
// working switch //
// runApp(
//
// MaterialApp(debugShowCheckedModeBanner: false, home: MyApp()),);
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body:
Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 100,
width: 100,
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => IntroPage(Isscar4: true)),
);
},
child: RichText(
text: TextSpan(
text: 'CAR',
style: TextStyle(
letterSpacing: 3,
color: Colors.white,
fontWeight: FontWeight.w400),
children: [
TextSpan(
text: '4',
style: TextStyle(
fontSize: 25,
color: Colors.red,
fontWeight: FontWeight.bold))
],
)),
),
),
],
),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 100,
width: 100,
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => IntroPage(Isscar4: false)),
);
},
child: RichText(
text: TextSpan(
text: 'BIKE',
style: TextStyle(
letterSpacing: 3,
color: Colors.white,
fontWeight: FontWeight.w400),
children: [
TextSpan(
text: '2',
style: TextStyle(
fontSize: 25,
color: Colors.red,
fontWeight: FontWeight.bold))
],
)),
),
),
],
)
])));
}
MaterialApp Swithwidget(istrue) {
return MaterialApp(
home: Scaffold(
body: IntroPage(
Isscar4: istrue,
),
),
);
}
}
class Hi extends StatelessWidget {
const Hi({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
child: Text("df"),
);
}
}
class IntroPage extends StatelessWidget {
final Isscar4;
IntroPage({
Key? key,
required this.Isscar4,
}) : super(key: key);
List<Widget> listPagesViewModel = [];
List<IntroModel> models = [];
#override
Widget build(BuildContext context) {
List<dynamic> intro = fetchIntroApi(Isscar4);
intro.forEach((element) {
var element2 = element as Map<String, dynamic>;
var cd = IntroModel.fromJson(element2);
models.add(cd);
});
models.forEach((element) {
listPagesViewModel.add(Text(""));
});
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Container(),
));
}
List fetchIntroApi(bool bool) {
var four = bool;
if (four) {
var data =
'[ {"name_Title": "title name1","description": "description1"}, {"name_Title": "title name2","description": "description2"}, {"name_Title": "title name3","description": "description3"}, {"name_Title": "title name4","description": "description4"} ]';
return json.decode(data);
} else {
var data =
'[ {"name_Title": "title name","description": "description1"}, {"name_Title": "title name2","description": "description2"}, {"name_Title": "title name3","description": "description3"} ]';
return json.decode(data);
}
}
}
class IntroModel {
String? nameTitle;
String? description;
IntroModel({this.nameTitle, this.description});
IntroModel.fromJson(Map<String, dynamic> json) {
nameTitle = json['name_Title'];
description = json['description'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name_Title'] = this.nameTitle;
data['description'] = this.description;
return data;
}
}
class Splash extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Splash Screen',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: MyState(),
debugShowCheckedModeBanner: false,
);
}
void main() {
runApp(Splash());
}
class MyState extends StatefulWidget{
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyState> {
#override
void initState() {
super.initState();
Timer(Duration(seconds: 3),
()=>Navigator.pushReplacement(context,
MaterialPageRoute(builder:
(context) =>
Login()
)
)
);
}
#override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center ,
children: [
Container(
child:
Image.asset("assets/images/herosplash.png"),
),
],
),
);
}
}
Builder(
builder: (context) {
return TextButton(
child: const Text('Bearbeiten'),
onPressed:(){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const gotothesiteyouwant()),
);
});
}
),
Here, all you need is to make MaterialApp the parent of your Build. This is because the context that you've used to navigate to a different screen is finding a MaterialApp or a WidgetApp as a parent of the build.
And Since in your case, the situation is the opposite, therefore you need to modify it by either calling a new Stateless widget the parent of is the MaterialApp or by simply using a Builder as home: Builder in MaterialApp.
Hope this would help!