How can we push to various pages without adding context in flutter? - flutter

What I am aiming for is that I have created around 5 stateful screens that are supposed to be navigated on button press. Now all the five buttons are same so I am using a for loop to assign those widgets and then add them to Column Widget list as shown below:
for(int i=0;i<ButtonTexts.length;i++)
{
NavigatorS.add(Container(
width: 300,
height: 40,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(NavigatorRadius),
side: BorderSide(color: NavigatorBorderColour)),
onPressed: (context)=>functionCalls[i],
color: NavigatorBarColour,
textColor: NavigatorTextColour,
child: Text(ButtonTexts[i],
style: TextStyle(fontSize: 20)),
),
));
}
Now the issue is that I have created a list of functions as shown below:
List functionCalls =[buildContext(context),buildContext2(context),buildContext3(context),buildContext4(context),buildContext5(context)];
But these functions need context to navigate to a different screen as the functions are defined as follows:
void buildContext(context)
{Navigator.push(context,MaterialPageRoute(builder: (context) => BirthdayCard()),);
}
Someone please help me with this, also I can't use route pages as I am operating on classes, my each screen dart file is nothing but a class of stateful widget. What I want is to avoid repetative coding and pass function definitions in the onpressed option.

Didn't get the exact problem that you are facing, anyway check this
void buildContext(context,screen)
{
Navigator.push(context,MaterialPageRoute(builder: (context) => screen),);
}
Widget getButton(onPressed) {
return RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(NavigatorRadius),
side: BorderSide(color: NavigatorBorderColour)),
onPressed: onPressed,
color: NavigatorBarColour,
textColor: NavigatorTextColour,
child: Text(ButtonTexts[i],
style: TextStyle(fontSize: 20)),
),
}
And in your code, you can call this,based on the conditions
getButton((){
buildContext(context,BirthdayCard());
}
);

Related

The argument type 'Color?' can't be assigned to the parameter type 'Color'

class _CreateRoomButton extends StatelessWidget {
#override
Widget build(BuildContext context) {
// ignore: deprecated_member_use
return OutlineButton(
onPressed: () => print('Create Room'),
color: Colors.white,
borderSide: BorderSide(width: 3.0, color: Colors.blueAccent[100]),
textColor: Palette.facebookBlue,
child: Row(
children: [
Icon(
Icons.video_call,
size: 35.0,
color: Colors.white,
)
],
),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)),
);
}
}
I have used an Outline Button in which I wanna set the border color to blueAccent[100]. On trying to do so the following error comes up :
The argument type 'Color?' can't be assigned to the parameter type 'Color'.
Also I wanna shift the outline button into the new Outlined Button but I am unable to style that acc to the app.
If you see Colors.blueAccent[100] actually gets a value from map. So if your version of flutter is bellow 2.0 you would get this error since it may return a null value.
Now why did this happen: This is because if you are using flutter 2.2 which is by default null-safe. You will get many errors.
Solution : Colors.blueAccent[100]! or Colors.blueAccent.shade100;
For OutlinedButton:
OutlinedButton.icon(
label: Text('MY BUTTON'),
icon: Icon(Icons.video_call),
onPressed: () {
print('Pressed');
},
style: OutlinedButton.styleFrom(
primary: Colors.white,
backgroundColor: Colors.teal,
shape: const RoundedRectangleBorder(borderRadius:
BorderRadius.all(Radius.circular(30))),
),
)
You can tap into more properties : From here or you can see this Material Guidelines or this blog This Blog
you have updated flutter sdk i think and using null safety feature. just add ! after color.
color: Colors.blueAccent[100]!,
Note : Outlinebutton is deprecated use outlinedbutton instead.
Flutter Outlinedbutton

Not able to import variable from a different class in Flutter

I am going off of a login screen tempalte,a nd am trying to get a widget class for a button to just show the username input as an alert on the screen. The usernameinput widget is defined but when I import it, it does not work.
class _InputEmailState extends State<InputEmail> {
final myController = new TextEditingController();
This is the part where I define the input, and this is where I import the class in the button widget:
import 'package:login_minimalist/widget/inputEmail.dart';
When I try and reference the myController.text value, I get the error
The getter 'myController' isn't defined for the class '_ButtonLoginState'.
import 'package:flutter/material.dart';
import 'package:login_minimalist/widget/inputEmail.dart';
class ButtonLogin extends StatefulWidget {
#override
ButtonLoginState createState() => ButtonLoginState();
}
class ButtonLoginState extends State<ButtonLogin> {
#override
Here is the button widget code:
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 40, right: 50, left: 200),
child: Container(
alignment: Alignment.bottomRight,
height: 50,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.blue[300],
blurRadius: 10.0, // has the effect of softening the shadow
spreadRadius: 1.0, // has the effect of extending the shadow
offset: Offset(
5.0, // horizontal, move right 10
5.0, // vertical, move down 10
),
),
],
color: Colors.white,
borderRadius: BorderRadius.circular(30),
),
child: FlatButton(
onPressed: () {
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
// Retrieve the text the user has entered by using the
// TextEditingController.
content: Text(InputEmailState.getUsername),
);
},
);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Sign in',
style: TextStyle(
color: Colors.lightBlueAccent,
fontSize: 14,
fontWeight: FontWeight.w700,
),
),
Icon(
Icons.arrow_forward,
color: Colors.lightBlueAccent,
),
],
),
),
),
);
And here is the Input code:
class InputEmailState extends State<InputEmail> {
final myController = new TextEditingController();
getUsername() {
return(myController.text);
}
#override
void dispose() {
// Clean up the controller when the widget is disposed.
myController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 50, left: 50, right: 50),
child: Container(
height: 60,
width: MediaQuery.of(context).size.width,
child: TextField(
controller: myController,
style: TextStyle(
color: Colors.white,
),
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Colors.lightBlueAccent,
labelText: 'Student ID',
labelStyle: TextStyle(
color: Colors.white70,
fontSize: 20,
),
),
),
),
);
}
If I understand your question correctly, you're trying to access _ButtonLoginState from another class/file. However, in Dart, classes, members, variables, etc. that begin with an underline ("_") are considered private. You can't access them from a different file (except in some special situations with libraries).
To solve this, you can change the name of the class to ButtonLoginState and it should work.
EDIT: In response to more info:
You don't seem to have fully understood the concepts of State in a StatefulWidget. I would strongly recommend taking a good look through the Flutter guide on the subject.
There are many different ways of managing state and what I am going to explain is almost definitely not the best option most of the time (this was the introductory approach some time ago, but I can't even find the example anymore), however, it does work. For a more general option, I recommend Provider.
In your case, the problem starts with this: Text(InputEmailState.getUsername). You're not calling InputEmailState.getUsername, you're simply passing a reference to it. You need to include parentheses to actually call it - InputEmailState.getUsername().
However, this isn't the whole issue. You're trying to access this function using the name of the class, which means you're trying to use it as a static method. However, its an instance method (ie: you need a specific instance of the class to access it. This is the state I was talking about.
To simply get access to the state object of a specific widget, you can use a Key (generally a GlobalKey). You can define this in a parent widget, for example, and pass it as the key parameter of your InputEmail widget and keep a reference in the parent class. Then, to get the username, you can call <key>.currentState.getUsername() which will return the instance value. The exact implementation varies, and I don't have your code to know how it should be implemented.
As I say, this isn't really the recommended approach anymore. I strongly recommend getting to grips with the state concept, then it should be obvious what the best approach is.

dynamically add a widget on press of button [duplicate]

This question already has an answer here:
Append items dynamically to ListView
(1 answer)
Closed 2 years ago.
I have created a class that has a widget that I want to appear on the home page as many times as the button is pressed.
https://gyazo.com/f9cc3e2c1f48e9efeb7b1d1c9b0b988e
as you can observe in this picture, the 'home care kit' rectangles is the widget, and I want them to appear when you press the add device button.
Here is the code of the button:
child: RaisedButton(
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40.0),
side: BorderSide(color: Colors.transparent)),
onPressed: () {print('Clicked!');},
color: Colors.transparent,
textColor: Colors.white,
child: Text('Add Device', style: TextStyle(color: Colors.white, fontSize: 18)),
),
and the widget class is simply called HomeCareKit()
You first need a list of widgets:
List<Widget> _widgetList = [];
and you pass this list of widgets to your ListView or Column like:
ListView(
children:_widgetList,
)
to add a widget dynamically you can do this inside your onPressed:
setState(() {
_widgetList.add(HomeCareKit());
});

RaisedButton vs ElevatedButton, FlatButton vs TextButton and OutlineButton vs OutlinedButton

I'm seeing the warning using old buttons:
'RaisedButton' is deprecated and shouldn't be used.
'FlatButton' is deprecated and shouldn't be used.
'OutlineButton' is deprecated and shouldn't be used.
So, what's the difference between:
RaisedButton and ElevatedButton
FlatButton vs TextButton
OutlineButton vs OutlinedButton
Here I found the docs for Migrating to the New Material Buttons and their Themes
The following image says itself what are the difference between all.
Visually, the new buttons look a little different, because they match
the current Material Design spec and because their colors are
configured in terms of the overall Theme’s ColorScheme. There are
other small differences in padding, rounded corner radii, and the
hover/focus/pressed feedback.
You can check Changes Overview for more about changes.
First are obsolete classes.
Quotes from the Flutter documentation:
FlatButton, RaisedButton, and OutlineButton have been replaced by TextButton, ElevatedButton, and OutlinedButton respectively.
The original classes will be deprecated soon, please migrate code that uses them.
These are obsolete classes, so eventually your old code needs to go away. (and, this document will help you do exactly that.) However, that can be a lot of work, so to get things moving, I created some code to migrate the FlatButton and RaisedButton to the new TextButton and ElevatedButton 'in place'. They are analogous to each other, but they approach styling in different ways, which this code handled.
Here's a link to the the gist if you want to run it in dartpad.dev (I couldn't get it to link directly):
https://gist.github.com/wterrill/7942b4bf5d74a8b2ace952ebf213fe5d
Here's the code itself:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
final bool disableButton = true; // <-- Change this to see buttons disabled
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FlatButton(
child: Text("FlatButton"),
onPressed: disableButton
? null
: () {
print("FlatButton normal");
},
color: Colors.green,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(50),
),
side: BorderSide(color: Colors.purple, width: 3.0)),
disabledColor: Colors.grey,
disabledTextColor: Colors.pink),
SizedBox(height: 25),
FlatButtonX(
childx: Text("TextButton"),
onPressedx: disableButton
? null
: () {
print("FlatButtonX (TextButton)");
},
colorx: Colors.green,
textColorx: Colors.black,
shapex: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(50),
),
side: BorderSide(color: Colors.purple, width: 3.0)),
disabledColorx: Colors.grey,
disabledTextColorx: Colors.pink),
SizedBox(height: 100),
RaisedButton(
child: Text('RaisedButton'),
color: Colors.green,
textColor: Colors.black,
onPressed: disableButton
? null
: () {
print("RaisedButton normal");
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(50),
),
side: BorderSide(color: Colors.purple, width: 3.0)),
disabledColor: Colors.grey,
disabledTextColor: Colors.pink,
),
SizedBox(height: 25),
RaisedButtonX(
childx: Text('ElevatedButton'),
colorx: Colors.green,
textColorx: Colors.black,
onPressedx:disableButton
? null
: () {
print("RaisedButtonX (ElevatedButton)");
},
shapex: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(50),
),
side: BorderSide(color: Colors.purple, width: 3.0)),
disabledColorx: Colors.grey,
disabledTextColorx: Colors.pink,
)
],
),
),
),
);
}
}
Widget FlatButtonX(
{Color colorx,
#required Widget childx,
RoundedRectangleBorder shapex,
#required Function onPressedx,
Key keyx,
Color disabledColorx,
Color disabledTextColorx,
Color textColorx}) {
if (disabledTextColorx == null && textColorx == null) {
disabledTextColorx = colorx;
}
if (textColorx == null) {
textColorx = colorx;
}
return TextButton(
key: keyx,
style: ButtonStyle(
foregroundColor: MaterialStateProperty.resolveWith<Color>(
// text color
(Set<MaterialState> states) => states.contains(MaterialState.disabled)
? disabledTextColorx
: textColorx,
),
backgroundColor: MaterialStateProperty.resolveWith<Color>(
// background color this is color:
(Set<MaterialState> states) =>
states.contains(MaterialState.disabled) ? disabledColorx : colorx,
),
shape: MaterialStateProperty.all(shapex),
),
onPressed: onPressedx as void Function(),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0), child: childx));
}
Widget RaisedButtonX(
{Color colorx,
#required Widget childx,
RoundedRectangleBorder shapex,
#required Function onPressedx,
Key keyx,
Color disabledColorx,
Color disabledTextColorx,
Color textColorx}) {
if (disabledTextColorx == null && textColorx == null) {
disabledTextColorx = colorx;
}
if (textColorx == null) {
textColorx = colorx;
}
return ElevatedButton(
key: keyx,
style: ButtonStyle(
foregroundColor: MaterialStateProperty.resolveWith<Color>(
// text color
(Set<MaterialState> states) => states.contains(MaterialState.disabled)
? disabledTextColorx
: textColorx,
),
backgroundColor: MaterialStateProperty.resolveWith<Color>(
// background color this is color:
(Set<MaterialState> states) =>
states.contains(MaterialState.disabled) ? disabledColorx : colorx,
),
shape: MaterialStateProperty.all(shapex),
),
onPressed: onPressedx as void Function(),
child: childx);
}
One of the advantages of ElevatedButton over RaisedButton is that it will actually pick up your main theme color by default.
So you don't even need to add that custom background color. You would only need to bring your own styling in ElevatedButton, if you want to deviate from your main theme or style other aspects of the button.
My understanding is that they are really equivalent. According to the Flutter 1.22 announcement, the main motivation was around styling. Prior to Flutter 1.22, there was only ONE ButtonTheme for 3 types of buttons, whereas now each type of button has its own theme.
The FlatButton, RaisedButton and OutlineButton widgets have been replaced by TextButton, ElevatedButton, and OutlinedButton respectively.
Link explaining changes:
https://flutter.dev/docs/release/breaking-changes/buttons
How to use the buttons:
https://flutter.dev/docs/development/ui/widgets/material
you can't set borderSide nor shape either on OutlinedButton even though you could on OutlineButton
Alternative buttons such as TextButton, ElevatedButton, and OutlinedButton are not quite easy like before. We can still use those legacy buttons using the legacy_buttons package
https://pub.dev/packages/legacy_buttons/

Alternative for Flutter Tap/Button component that have great responsiveness/sensitiveness?

In my application I use inkwell/flat button/ink response/Gesture Detector/RaisedButton, etc for my tap component. The application already in release Alpha channel (Android) and Test Flight (IOS). However the user is not satisfied with the result, because all the button is less responsive/sensitive compare to native button component (Android/iOS). Is there any alternative or another way in Flutter to create tapable widget or button that have responsiveness similar with native application?
Example code:
InkWell(
onTap: () => Navigator.of(context).pushNamed(
Routes.MEMBERSHIP,
arguments: membershipPlanModel),
child: Card(
margin: EdgeInsets.only(
right: 16,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10))),
child: Container(...
Another code:
FlatButton(
onPressed: () async {
_cancelTransaction();
Navigator.of(context).pop(true);
Navigator.of(context).pop(true);
},
child: Text(
Labels.YES,
style: Fonts.GHOST,
),
),