Flutter Floating Action Button issue in opening SimpleDialog or Bottom Sheet - flutter

I have a Main Dart File with the Bottom Navigation bar and Floating action button.
I am trying to open SimpleDialog or showModalBottomSheet when the user taps on the Button. But this is not working.
I have tried another way to open it. But that also does not work.
I am sure the problem is with the context. With the right context, the dialog should get open.
What's the right solution to tackle this As if this floating action button is added in one of the Screens from the Bottom navigation then the BottomSheetModal gets opened.
Navigator.of(context).push(new MaterialPageRoute<Null>(
builder: (BuildContext context) {
return SimpleDialog(
title:Text("hello"),
);
},
fullscreenDialog: true
));
}
Sample code can be found here
https://github.com/parmarravi/Flutter-BottomSheet-Bug

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: 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> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
showDialog(
context: context,
builder: (context) {
return AlertDialog(
backgroundColor: Color(0xFFFFFFDD),
shape: RoundedRectangleBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(20),
),
side: BorderSide(
color: Theme.of(context).primaryColor,
width: 2,
),
),
title: Column(
children: [
Text(
'title',
),
],
),
content: Container(
child: Text(
'body!',
),
),
actions: [
Container(
height: 50,
child: TextButton(
onPressed: (){},
child: Text(
'Ok',
),
),
)
],
);
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

Related

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

//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()));
}
}

Flutter get text from widgets

I am coming from java and now making my very initial steps with flutter.
In my first application I am playing around with the layouts and the buttons and I am facing difficulties getting the button actions to work, probably due to my coming from from java.
In my app I have, among others, the following widgets:
Widget _buttonOne = RaisedButton(
onPressed: () {},
child: Text('Button One', style: TextStyle(fontSize: 20)),
);
final _textContainer =
const Text('Container One', textAlign: TextAlign.center);
Container(
padding: const EdgeInsets.all(8),
child: _textContainer,
color: Colors.teal[200],
),
Now I want to print the text of the button and textchild of the container. How do I achieve that?
CupertinoButton.filled(
child: Text('Button Two'),
onPressed: () {
print(_textContainer); // how do I print the text of the text widget here?
print (_buttonOne. ....); // on java there is a getText() method .... how does this work in flutter?
),
You can access the text of a Text widget by using the data property:
final _textContainer =
const Text('Container One', textAlign: TextAlign.center);
#override
Widget build(BuildContext context) {
return Scaffold(body:
Center(
child: CupertinoButton.filled(
child: Text('Button Two'),
onPressed: () =>
{print(_textContainer.data)},
)
)
);
}
In a similar fashion, you could access the content of the RaisedButton child:
final _raisedButtonText = const Text('Button One', style: TextStyle(fontSize: 20));
Widget _buttonOne = RaisedButton(onPressed: () {}, child: _raisedButtonText);
final _textContainer =
const Text('Container One', textAlign: TextAlign.center);
#override
Widget build(BuildContext context) {
return Scaffold(body:
Center(
child: CupertinoButton.filled(
child: Text('Button Two'),
onPressed: () {
print(_textContainer.data);
print(_raisedButtonText.data);
}
)
)
);
}
You can copy paste run full code below
You can use as to do type casting then access attribute data
code snippet
CupertinoButton.filled(
child: Text('Button Two'),
onPressed: () {
print(_textContainer.data);
print(((_buttonOne as RaisedButton).child as Text).data);
}),
output
I/flutter (30756): Container One
I/flutter (30756): Button One
full code
import 'package:flutter/cupertino.dart';
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: 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> {
Widget _buttonOne = RaisedButton(
onPressed: () {},
child: Text('Button One', style: TextStyle(fontSize: 20)),
);
final _textContainer =
const Text('Container One', textAlign: TextAlign.center);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CupertinoButton.filled(
child: Text('Button Two'),
onPressed: () {
print(_textContainer
.data); // how do I print the text of the text widget here?
print(((_buttonOne as RaisedButton).child as Text).data);
}),
],
),
),
);
}
}

Flutter navigator not working : OnPress not showing second screen

This is my code don't know why its not moving to screen 2 on button press:
Am beginner in dart/flutter please help. On press of button it's not showing screen2
//main.dart
import 'package:flutter/material.dart';
import 'screen_1.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Screen1(),
);
}
}
//screen_1.dart
import 'package:flutter/material.dart';
import 'screen_2.dart';
class Screen1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Screen 1'),
),
body: Container(
child: Center(
child: RaisedButton(
color: Colors.pink,
child: Text(
'Go to Screen 2',
style: TextStyle(
color: Colors.white,
),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return Screen2();
},
),
);
},
),
),
),
);
}
}
//screen_2.dart
import 'package:flutter/material.dart';
class Screen2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text('Screen 2'),
),
body: Center(
child: RaisedButton(
color: Colors.blue,
child: Text('Go Back To Screen 1'),
onPressed: () {},
),
),
);
}
}
onPressed of Screen1 class should show Screen2 but it's not happening.
I tried this and it does move to Screen2:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Screen1(),
);
}
}
//screen_1.dart
class Screen1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Screen 1'),
),
body: Container(
child: Center(
child: RaisedButton(
color: Colors.pink,
child: Text(
'Go to Screen 2',
style: TextStyle(
color: Colors.white,
),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return Screen2();
},
),
);
},
),
),
),
);
}
}
//screen_2.dart
class Screen2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text('Screen 2'),
),
body: Center(
child: RaisedButton(
color: Colors.blue,
child: Text('Go Back To Screen 1'),
onPressed: () {},
),
),
);
}
}
This may be because StatelessWidget is part of material.dart yet you failed to import it in the first dart file.

How to add navigation route to Card in Flutter

In the code below, I have a method myMenu on a card. How do I navigate to another page when the card is tapped? There are going to be several of these cards which will link to its own page content. Each time I add a function to for an example it gives an error. How do I do it properly?
import 'package:flutter/material.dart';
import 'package:tarjous_app/gridview_demo.dart';
void main(List<String> args) {
runApp(
new MaterialApp(home: TarjousAle(), debugShowCheckedModeBanner: false));
}
class TarjousAle extends StatefulWidget {
#override
_TarjousAleState createState() => _TarjousAleState();
}
class _TarjousAleState extends State<TarjousAle> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: Text("Study Plan"),
backgroundColor: Colors.amber,
),
body: Container(
child: GridView.count(
crossAxisCount: 3,
children: <Widget>[
MyMenu(
title: "Records",
icon: Icons.account_balance_wallet,
shape: Colors.brown,
),
MyMenu(
title: "Academy",
icon: Icons.account_balance,
shape: Colors.grey,
),
],
),
),
);
}
}
class MyMenu extends StatelessWidget {
MyMenu({this.title, this.icon, this.shape});
final String title;
final IconData icon;
final MaterialColor shape;
#override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.all(9.0),
child: InkWell(
onTap: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => GridViewDemo()),
),
splashColor: Colors.amberAccent,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
icon,
size: 80.0,
color: shape,
),
Text(title, style: new TextStyle(fontSize: 18.0))
],
),
),
),
);
}
}
In the inkwell widget, I add a function that works for all the cards. But what I really want it for each card to navigate to its own page. E.g Records should navigate to its own records page, the same thing for Academy to academy page
You could receive the page in the constructor and then go to that page, like this:
class MyMenu extends StatelessWidget {
MyMenu({this.title, this.icon, this.shape, this.page});
final Widget page;
...
}
Then, in onTap:
onTap: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => page),
)
So now you can do this:
MyMenu(
...
page: GridViewDemo1(),
),
MyMenu(
...
page: GridViewDemo2(),
)
Note that to navigate to some page, your context must contain a Navigator instance of parent. So if you try to navigate directly from MaterialApp, you might run into issues. I will not belabour the point here since it was explained very well in this thread, but it is something to keep in mind in case you happen to run into it.
Edited to address comments:
I'd do something like this for your case. Named routes make it easy to specify which route you'd like the card to take you to, which you kind of need to do if you want the same widget to take you to different routes.
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(
new MaterialApp(
home: TarjousAle(),
debugShowCheckedModeBanner: false,
routes: {
GridViewDemo.route: (context) => GridViewDemo(),
AnotherDemo.route: (context) => AnotherDemo(),
},
),
);
}
class TarjousAle extends StatefulWidget {
#override
_TarjousAleState createState() => _TarjousAleState();
}
class _TarjousAleState extends State<TarjousAle> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: Text("Study Plan"),
backgroundColor: Colors.amber,
),
body: Container(
child: GridView.count(
crossAxisCount: 3,
children: <Widget>[
MyMenu(
title: "Records",
icon: Icons.account_balance_wallet,
shape: Colors.brown,
route: GridViewDemo.route
),
MyMenu(
title: "Academy",
icon: Icons.account_balance,
shape: Colors.grey,
route: AnotherDemo.route
),
],
),
),
);
}
}
class MyMenu extends StatelessWidget {
MyMenu({this.title, this.icon, this.shape, this.route});
final String title;
final IconData icon;
final MaterialColor shape;
final String route;
#override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.all(9.0),
child: InkWell(
onTap: () => Navigator.pushNamed(context, route),
splashColor: Colors.amberAccent,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
icon,
size: 80.0,
color: shape,
),
Text(title, style: new TextStyle(fontSize: 18.0))
],
),
),
),
);
}
}
class GridViewDemo extends StatelessWidget {
static String route = '/demo';
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.brown,
appBar: AppBar(title: Text('Grid view demo')),
body: Center(
child: Text('Grid view demo'),
),
);
}
}
class AnotherDemo extends StatelessWidget {
static String route = '/another';
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(title: Text('Another demo')),
body: Center(
child: Text('Another demo'),
),
);
}
}
You can read more about the basics of navigation in official docs, and also another docs page if you fancy the named routes.
Wrap the card with GestureDetector and you can use opnTap property.
for more details Official Documentation
Try wrapping your Card in a GestureDetector like below:
GestureDetector (
child: Card(),
onTap: () {},
),
wrap the card with InkWell widget and define your navigator.push in the onTap method.
class CardWidget extends StatelessWidget {
final Function onTapCard;
const CardWidget({Key key, #required this.onTapCard}) : super(key: key);
#override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.all(9.0),
child: InkWell(
onTap: onTapCard,
splashColor: Colors.amberAccent,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
icon,
size: 80.0,
color: shape,
),
Text(title, style: new TextStyle(fontSize: 18.0))
],
),
),
),
);
}
}
then we have our list here
class CardList extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
CardWidget(
onTapCard: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => YourSecondPage()),
),
),
CardWidget(
onTapCard: Navigator.push(
context,
MaterialPageRoute(builder: (context) => YourThirdPage()),
),
),
],
);
}
}

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,
),
),
),
)
],
),
),
);
}
}