Navigator operation requested with a context that does not include a Navigator even though second route has context - flutter

//main.dart file
import 'package:flutter/material.dart';
import 'package:messenger/widgets/splash_screen.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
scaffoldBackgroundColor: Colors.white,
appBarTheme: AppBarTheme(
brightness: Brightness.light,
color: Colors.white,
elevation: 0.0,
iconTheme: IconThemeData(color: Colors.black),
actionsIconTheme: IconThemeData(color: Colors.black)),
fontFamily: "Ubuntu",
primarySwatch: Colors.blue,
primaryColor: Color(0xff0084FF),
),
home: Column(
children: <Widget>[
SizedBox(height: 30.0,),
ElevatedButton(
onPressed: () => navigation(context),
child: Text("to splash screen"))
],
),
);
}
navigation(BuildContext context) {
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>SplashScreen()));
}
}
//SplashScreen.dart file
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:messenger/widgets/login_button.dart';
class SplashScreen extends StatefulWidget {
#override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
#override
Widget build(BuildContext context) {
double imageSize = MediaQuery.of(context).size.width / 3;
return Scaffold(
body: Center(
child: Image.asset(
"images/logo.png",
width: imageSize,
height: imageSize,
fit: BoxFit.cover,
),
),
bottomNavigationBar: Padding(
padding: EdgeInsets.symmetric(
horizontal: 16.0,
vertical: 16.0,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
LoginButton(text: "Continue with Facebook",onPressed: (){
},
colour: Color(0xff3b5998),
leading: Image.asset("images/facebook-logo.png",
),
),
],
),
),
);
}
}
Navigator operation requested with a context that does not include a Navigator.
Maybe I didn't understand the concept of context well that's why I am getting the
error.Why is this error happening? The second widget that is SplashScreen has
context. But still I am getting the error. Is there any problem in the code that I
missed?

bro you its not good way to call Navigator.push in Navigator please try to call in specific function or you can call this in ink well so please remove
the **Navigator(BuildContext context)**after thats its will work fine for you.

**here is the code that can solve your navigation problem **
enter code here
import 'package:flutter/material.dart';
import 'screen/splashScreen.dart';
class DemoNavigation extends StatefulWidget {
const DemoNavigation({Key? key}) : super(key: key);
#override
_DemoNavigationState createState() => _DemoNavigationState();
}
class _DemoNavigationState extends State<DemoNavigation> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
child: Column(
children: [
Text("Navigator Demo"),
ElevatedButton(
onPressed: () {
// here is the function that your are using
navigation(context);
},
child: Text("TO Next Screen"),
),
],
),
),
);
}
/// here you need to change the context that your are passing to build
/// copy this
void navigation(BuildContext context) {
Navigator.push(context, MaterialPageRoute(builder: (_) =>
SplashScreen()));
}
}

Related

How can I use a provider in a custom widget to change the variables within a provider?

I tried to create a function to adjust the font size on the setting screen, so I made a provider.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class CountPage extends ChangeNotifier{
double _font = 40;
double get font => _font;
change_font_1()
{
_font = 30;
notifyListeners();
}
change_font_2()
{
_font = 35;
notifyListeners();
}
change_font_3()
{
_font = 40;
notifyListeners();
}
And I created an option screen custom widget
Code related to font size:
class Option_page extends StatelessWidget {
late CountPage _countPage;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red[200],
centerTitle: true,
title: Text("설정"),
),
body: Center(
child: Container(
child: Column(children: [
Container(
height: 50,
child: Row(children: [
Container(child: Text('글자크기')),
Container(
width: 300,
color: Colors.cyan,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
IconButton(
onPressed: () {
_countPage.change_font_1();
},
icon: Icon(Icons.looks_one_outlined)),
IconButton(
onPressed: () {
_countPage.change_font_2();
},
icon: Icon(Icons.looks_two_outlined)),
IconButton(
onPressed: () {
_countPage.change_font_3();
},
icon: Icon(Icons.looks_3_outlined)),
],
),
)
]))
]))));
}
}
I connected with the main class:
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
home:ChangeNotifierProvider(
create: (BuildContext context) => CountPage()
,child: Quote() ,)
);
}
}
Code related to font size in the main class:
class Quote extends StatelessWidget {
Quote({Key? key}) : super(key: key);
late CountPage _countPage;
#override
Widget build(BuildContext context) {
_countPage = Provider.of<CountPage>(context, listen: true);
return Scaffold(
body: Container(
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Center(
child: IconButton(
onPressed: () {
_countPage.page_down();
},
icon: Icon(Icons.chevron_left))),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Container(
color: Colors.white,
height: 400,
width: 350,
child: Center(
child: Text(
list[_countPage.page]["message"],
style: TextStyle(
fontSize: _countPage.font,
fontFamily: 'snow',
),
textAlign: TextAlign.center,
))),
),
Container(
height: 40,
width: 300,
color: Colors.white,
child: Center(
child: Text(
list[_countPage.page]["author"],
style: TextStyle(fontSize: 20, color: Colors.black),
)))
],
),
],
),
),
);
}
}
The font size does not change even if you run it on Chrome and press the font size change button. I don't know what the problem is.
You can wrap the MaterialApp to access provider on all route
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (BuildContext context) => CountPage(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
home: Quote(),
),
);
}
}
From current snippet, you didnt assign the CountPage on Option_page.
class Option_page extends StatelessWidget {
Widget build(BuildContext context) {
CountPage _countPage = Provider.of<CountPage>(context, listen: true); //this ibe
return Scaffold(
appBar: AppBar(

Error Message: The return type 'void' isn't a 'Widget', as required by the closure's context

Whenever I want to navigate to next page with specific time, the destination page isn't found, even I imported the page. Instead of Navigation, if I print something, It works OK. Error line is highlighted in bold inside code.
import 'package:flutter/material.dart';
import 'dart:async';
import 'main.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: "Flutter App",
theme: ThemeData(
appBarTheme: AppBarTheme(
color: Colors.deepOrangeAccent,
),
primarySwatch: Colors.indigo,
),
home: LoginScreen(),
);
}
}
class LoginScreen extends StatefulWidget {
const LoginScreen({Key? key}) : super(key: key);
#override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
#override
void initState() {
// TODO: implement initState
super.initState();
Timer(Duration(seconds: 5), () {
// 5 seconds over, navigate to Page2.
**Navigator.of(context).push(MaterialPageRoute(builder: (context)=>main()));****
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.indigo,
body: Padding(
//padding: const EdgeInsets.all(20.0),
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Image.asset(
"assets/images/logo.png",
//fit: BoxFit.fitWidth,
height: 200,
width: 200,
),
),
//CircularProgressIndicator(),
SizedBox(
height: 20,
),
Text(
"Fresh Food Restaurant",
style: TextStyle(
color: Colors.deepOrangeAccent,
fontSize: 25,
fontWeight: FontWeight.w900,
),
),
SizedBox(
height: 150,
),
// CircularProgressIndicator(
// backgroundColor: Colors.deepOrangeAccent,
// ),
// SizedBox(
// height: 10,
// ),
// Text(
// "Loading, Please wait",
// style: TextStyle(
// color: Colors.white,
// ),
// ),
SizedBox(
height: 100,
),
FloatingActionButton(
backgroundColor: const Color(0xff03dac6),
foregroundColor: Colors.black,
onPressed: () {
},
child: Icon(Icons.arrow_forward),
)
],
),
),
),
);
}
}
Main is not a widget and Navigator need Widget to push, like this:
Timer(Duration(seconds: 5), () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => MyApp()));
});
or
Timer(Duration(seconds: 5), () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => LoginScreen()));
});
but not a method void.
You are trying to navigate to a method:
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>main()));
This method 'main()' is defined above:
void main() {
runApp(const MyApp());
}
You have to pay attention to upper and lower case writing (If your widget is called Main()).
Instead of using it in init state use it in Build Widget
// 5 seconds over, navigate to Page2.
**Navigator.of(context).push(MaterialPageRoute(builder: (context)=>main()));****
});
Another MEthod is here
if(mounted){ Future.delayed(Duration(seconds:5)).then((_)=>
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>main()));
);}
}

Expandable button overflowing top of container

I'm trying to make an expandable button, a bit like the expandable fab, except it's not a fab as it is not floating. This is the expandable fab for perspective:
What I'm trying to achieve though is to have a self contained button that expands above it with a menu. Self contained is in bold because I'd like the widget to be used easily without having to modify the parents structure.
So if you copy paste the code below in dartpad you'll see a yellow bar at the bottom. However if you uncomment the lines which are commented, which represents the menu expanding, you'll see that the bottom bar is pushed to the top.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
children: [
Expanded(child: Container(color: Colors.purple)),
MyWidget(),
]
),
),
),
);
}
}
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SizedOverflowBox(
size: Size(double.infinity, 100),
child: Stack(
children: [
Container(color: Colors.amber, height: 100),
// Transform.translate(
// offset: Offset(0, -400),
// child: Container(color: Colors.lightBlue, height: 400, width: 80),
// ),
]
)
);
}
}
So my questions are:
How do I achieve the required result where the bottom bar does not move and a menu above it (light blue container); modifying only MyWidget and not MyApp ?
Why in the current code the bar is pushed above ?
Overlay and OverlayEntry can help to achieve this:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
children: [
Expanded(child: Container(color: Colors.purple)),
MyWidget(),
]
),
),
),
);
}
}
class MyWidget extends StatelessWidget {
OverlayEntry? _overlayEntry;
_hideMenu() {
_overlayEntry?.remove();
}
_showMenu(BuildContext context) {
final overlay = Overlay.of(context);
_overlayEntry = OverlayEntry(
builder: (ctx) => Stack(
children: [
GestureDetector(
onTap: () => _hideMenu(),
child: Container(color: Colors.grey.withAlpha(100)),
),
Positioned(
bottom: 100,
left: 50,
child: Container(color: Colors.pink, height: 200, width: 50,),
),
],
)
);
overlay?.insert(_overlayEntry!);
}
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => _showMenu(context),
child: Container(color: Colors.amber, height: 100)
);
}
}
Try this, run this code in dartpad.
It contains one parent, three child which can be called using the menu buttons,
The FloatingActionButton.extended used in this code can be replaced by any custom Widget, you can give onTap methods for clicks,
I have used simple widgets, Let me know wether you were looking for something like that, or something different.
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
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: MyHomePage(title: 'I am Parent'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool showButtons = false;
var index = 0;
List<Widget> childList = [Child1(), Child2(), Child3()];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: childList[index],
),
floatingActionButton: Column(
mainAxisSize: MainAxisSize.min,
children: [
Visibility(
visible: showButtons,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
FloatingActionButton.extended(
heroTag: 'btn1',
onPressed: () {
setState(() {
index = 0;
});
},
label: Text(
"Sub Btn1",
style: TextStyle(color: Colors.black),
),
elevation: 3,
backgroundColor: Colors.yellowAccent,
),
Padding(
padding: EdgeInsets.only(top: 3),
child: FloatingActionButton.extended(
heroTag: 'btn1',
onPressed: () {
setState(() {
index = 1;
});
},
label: Text(
"Sub Btn2",
style: TextStyle(color: Colors.black),
),
elevation: 3,
backgroundColor: Colors.yellowAccent,
)),
Padding(
padding: EdgeInsets.only(top: 3),
child: FloatingActionButton.extended(
heroTag: 'btn3',
onPressed: () {
setState(() {
index = 2;
});
},
label: Text(
"Sub Btn3",
style: TextStyle(color: Colors.black),
),
elevation: 3,
backgroundColor: Colors.yellowAccent,
))
],
),
),
RaisedButton(
onPressed: () {
setState(() {
showButtons = !showButtons;
});
},
child: Text("Self Contained"),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16)),
color: Colors.yellow,
),
],
) // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class Child1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Center(
child: Text("I am Child 1"),
);
}
}
class Child2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Center(
child: Text("I am Child 2"),
);
}
}
class Child3 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Center(
child: Text("I am Child 3"),
);
}
}

Open a modal or a dialogue after navigation in Flutter

After calling Navigator pushReplacement, I arrive at a screen where I'd like to open a modal or a dialog automatically after the screen loads. I'm trying to do that using Timer.run inside initState() but it doesn't work, it doesn't show any errors as well. Could anyone help me understand what am I missing here?
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:async';
class AfterSplash extends StatefulWidget {
#override
_AfterSplashState createState() => _AfterSplashState();
}
class _AfterSplashState extends State<AfterSplash> {
void initState() {
super.initState();
Timer.run(() {
showDialog(
context: context,
builder: (_) => AlertDialog(title: Text("Dialog title")),
);
});
}
#override
Widget build(BuildContext context) {
return opacityLogoTitle();
}
}
Widget opacityLogoTitle() {
return Scaffold(
body: Opacity(
opacity: 0.5,
child: Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
child: Image(image: AssetImage('assets/images/main.png')),
),
),
),
Text(
'Sample App',
style: TextStyle(
fontFamily: 'SF Pro Display',
fontSize: 60,
color: Color.fromRGBO(105, 121, 248, 1),
),
),
],
),
),
),
);
}
It's my test code with your code.
It works well.
import 'dart:async';
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,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
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
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: AfterSplash(),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class AfterSplash extends StatefulWidget {
#override
_AfterSplashState createState() => _AfterSplashState();
}
class _AfterSplashState extends State<AfterSplash> {
void initState() {
super.initState();
Timer.run(() {
showDialog(
context: context,
builder: (_) => AlertDialog(title: Text("Dialog title")),
);
});
}
#override
Widget build(BuildContext context) {
return opacityLogoTitle();
}
}
Widget opacityLogoTitle() {
return Scaffold(
body: Opacity(
opacity: 0.5,
child: Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Container(child: Text('asdf')),
),
),
Text(
'Sample App',
style: TextStyle(
fontFamily: 'SF Pro Display',
fontSize: 60,
color: Color.fromRGBO(105, 121, 248, 1),
),
),
],
),
),
),
);
}

Style clipboard in flutter

I am looking for a way to style the clipboard actions without touching textTheme/button property of the main style theme. Is this even possible?
Seems like the style is directly tied to the theme. Not the best idea but if you really wanted to you would need to create a custom popup and handle all the actions yourself.
This should get you started...
Output:
Code:
import 'package:flutter/material.dart';
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: 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> {
final _controller = new TextEditingController();
final _textfieldFocusNode = new FocusNode();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.all(20.0),
child: GestureDetector(
// intercept all pointer calls
behavior: HitTestBehavior.opaque,
onTap: () {
FocusScope.of(context).requestFocus(_textfieldFocusNode);
},
onLongPress: () {
showMenu(
context: context,
// TODO: Position dynamically based on cursor or textfield
position: RelativeRect.fromLTRB(0.0, 300.0, 300.0, 0.0),
items: [
PopupMenuItem(
child: Row(
children: <Widget>[
// TODO: Dynamic items / handle click
PopupMenuItem(
child: Text(
"Paste",
style: Theme.of(context)
.textTheme
.body2
.copyWith(color: Colors.red),
),
),
PopupMenuItem(
child: Text("Select All"),
),
],
),
),
],
);
},
child: IgnorePointer(
// ensures textfield doesn't overrule GestureDetector
child: TextField(
focusNode: _textfieldFocusNode,
controller: _controller,
),
),
),
)
],
),
),
);
}
}