Navigating to a new page with button class - flutter

This is my buttons class. I want to use its on pressed function to navigate to another page.
class DigerButtonu extends StatelessWidget {
final String butonyazisi;
final IconData butoniconu;
final Function butonfonksiyonu;
const DigerButtonu(this.butonyazisi,this.butonfonksiyonu,this.butoniconu);
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(left: 20,right: 20),
width: 50,
height: 550,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Color(0xFF15182D).withOpacity(0.4),
blurRadius: 8,
spreadRadius: 2,
offset: Offset(4,4),
),
],
borderRadius: BorderRadius.all(Radius.circular(10)),
border: Border.all(
color: Colors.black,
width: 0.2,
)
),
child: ElevatedButton(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Icon(butoniconu, color: Colors.white,size: 22,),
MyVerticalText(butonyazisi),
Icon(butoniconu, color: Colors.white,size: 22,),
],
),
style: ElevatedButton.styleFrom(
primary: Color(0xFF15182D),
onPrimary: Colors.white,
onSurface: Colors.grey,
//elevation: 0,
),
onPressed: (){
butonfonksiyonu;
},
),
);
}
}
But when i try to use the code below, it says 'The argument type 'Future'can't be assigned to the parameter type 'Function' '. How can i use it?
DigerButtonu('AYARLAR',Navigator.push(context,MaterialPageRoute(builder: (context) => clicker()), route),Icons.settings_rounded)

You can simply use lambdas for passing functions. Currently you pass the result of your method and not the method itself.
Here is your code with the corresponding lambda expression:
DigerButtonu('AYARLAR', () => Navigator.push(context,MaterialPageRoute(builder: (context) => clicker()), route),Icons.settings_rounded)

Related

Pass a parameters to stateful class

How can I pass a parameters to a stateful class in flutter?
I couldn't pass a parameter in the class as I'm a beginner and don't know the method.
I want to pass data from a list to build the class x times, and display the data in a container.
The text I want to pass is labeled tH.
I hope if someone can pass the argument for me.
My class:
class Thkr extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _ThkrState();
}
}
class _ThkrState extends State<Thkr> {
int Thkr_count = 3;
void _incrementCounter() {
setState(() {
Thkr_count--;
});
}
#override
Widget build(BuildContext) {
return (Column(children: [
Container(
padding: EdgeInsets.all(35),
margin: EdgeInsets.all(20),
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 3),
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.lightGreen,
offset: Offset(6.0, 6.0),
),
],
),
child: Text({here I want to pass the data},
style: TextStyle(fontSize: textSize, color: themeli[themei])),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Card(
child: SizedBox(
width: 100,
height: 30,
child: Center(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.lightGreen,
minimumSize: Size.fromHeight(40), //
),
onPressed: () {
_incrementCounter();
},
child: Text(
'Count',
style: TextStyle(color: themeli[themei]),
),
)),
),
),
Card(
child: SizedBox(
width: 100,
height: 30,
child: Center(
child: Text("$Thkr_count left",
style: TextStyle(
backgroundColor: Colors.white12,
))),
),
),
],
)
]));
}
}

How to toggle boolean value received from another widget

I would like to pass boolean initial boolean values as arguments to a stateful widget and then change its value besides updating the UI. As it stands, I only see the initial value and am not able to toggle the value. The code and the screenshots are as follows:
This is the widget from which I'm passing the arguments:
class OtherStuff extends StatefulWidget {
OtherStuffState createState() => OtherStuffState();
}
class OtherStuffState extends State<OtherStuff> {
#override
Widget build(BuildContext context) {
var provider = Provider.of<ModelClass>(context).data;
// TODO: implement build
return Container(
width: double.infinity,
height: 150,
color: Colors.transparent,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.only(left: 5),
child: const Text('Gets more interested with this', style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18
)),
),
SizedBox(height: 5),
Row(
children: [
StuffCards('https://static.toiimg.com/thumb/60892473.cms?imgsize=159129&width=800&height=800', false), //passing first value as false
SizedBox(width: 10),
StuffCards('https://thestayathomechef.com/wp-content/uploads/2016/06/Fried-Chicken-4-1.jpg', true), //passing second value as true
SizedBox(width: 10),
StuffCards('https://www.foodrepublic.com/wp-content/uploads/2012/03/033_FR11785.jpg', false), //passing third value as false
],
)
],
)
);
}
}
The stateful widget:
class StuffCards extends StatefulWidget {
final String imageUrl;
final bool clickedValue; //receiving the argument
StuffCards(this.imageUrl, this.clickedValue);
StuffCardsState createState() => StuffCardsState();
}
class StuffCardsState extends State<StuffCards> {
#override
Widget build(BuildContext context) {
var clicked = widget.clickedValue;
void clickedFav() {
setState(() {
clicked = !clicked; //toggling the value received
});
}
// TODO: implement build
return Stack(
children: [
// Container(
// width: 120,
// ),
Positioned(
child: Container(
width: 110,
height: 120,
margin: const EdgeInsets.only(left: 10),
decoration: BoxDecoration(
color: Theme.of(context).primaryColorDark,
borderRadius: const BorderRadius.only(
topRight: Radius.circular(100),
topLeft: Radius.circular(100),
bottomRight: Radius.circular(20),
bottomLeft: Radius.circular(20),
)
),
child: Padding(
padding: const EdgeInsets.only(top: 60),
child: Container(
width: double.infinity,
height: 60,
decoration: BoxDecoration(
color: Theme.of(context).primaryColorDark,
),
child: Column(
children: [
Text('Fried Squid', style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white
)),
Container(
width: 75,
color: Colors.transparent,
child: Text(
'₹ 245', style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 20
)),
),
Container(
width: double.infinity,
height: 16,
padding: EdgeInsets.only(right: 2, bottom: 1),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
InkWell(
onTap: clickedFav, //The inkwell doesn't seem to respond and update the UI
child: clicked ? Icon(
Icons.favorite,
color: Colors.red,
size: 15
) : Icon(
Icons.favorite_border,
color: Colors.white,
size: 15
)
)
],
),
)
],
),
),
),
),
),
Strangely enough, upon clicking the Inkwell widget, the value does get changed i.e If I click it and if the boolean value is false, it gets changed to true but doesn't change back to false. Also, as stated again, the UI doesn't update.
Your UI doesn't change because
StuffCards('https://static.toiimg.com/thumb/60892473.cms?imgsize=159129&width=800&height=800', false),
Will never change. When you call setstate in the StuffCards class, the widget gets a rebuild, but with the same parameters.
So you have two options here
you make a function in the OtherStuffState class that toggles the value, and you pass that function on to the StuffCards class, en you call that function when the ontap event occurs in the InkWell.
you use provider to store the data and you make a function in the modelclass to toggle the card, so you just have to call in the StuffCards class context.read<ModelClass>().toggleCard(cardNumber)

Passing function as parameter to a widget

I have a button that calls a widget to open a custom dialog:
child: GestureDetector(
onTap: () {
showDialog(
context: context,
builder: (context){
return MovMapAlert(
titulo: "yasiguiendo".tr(),
texto: "dejarsiguiendo".tr(),
aceptar: "dejardeseguir".tr(),
cancelar: "cancelar".tr(),
funcion: SeguidoresCrud().dejarDeSeguir(documentIdSeguidores),);
});
},
child: Image.asset('assets/profile/boton_follow_rojo.png'),
)
)
As you may see,I am posting some parameters to the custom dialog widget, including a function that should be executed when the user taps on a dialog button.
Here you have the custom dialog widget:
class MovMapAlert extends StatelessWidget {
final String titulo;
final String texto;
final String aceptar;
final String cancelar;
final Function funcion;
const MovMapAlert({Key key, this.titulo, this.texto, this.aceptar, this.cancelar, this.funcion}) : super(key: key);
#override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16)
),
elevation: 0,
backgroundColor: Colors.transparent,
child: _buildChild(context),
);
}
_buildChild(BuildContext context) => Container(
height: 350,
decoration: BoxDecoration(
color: Colors.redAccent,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(12))
),
child: Column(
children: <Widget>[
Container(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Image.asset('assets/images/movmap_transparente1024.png', height: 120, width: 120,),
),
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12))
),
),
SizedBox(height: 24,),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(this.titulo, style: TextStyle(fontSize: 20, color: Colors.white, fontWeight: FontWeight.bold),),
),
SizedBox(height: 8,),
Padding(
padding: const EdgeInsets.only(right: 16, left: 16),
child: Text(this.texto, style: TextStyle(fontSize: 18,color: Colors.white), textAlign: TextAlign.center,),
),
SizedBox(height: 24,),
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
FlatButton(onPressed: (){
Navigator.of(context).pop();
}, child: Text(this.cancelar),textColor: Colors.white,),
SizedBox(width: 8,),
RaisedButton(onPressed: (){
return Navigator.of(context).pop(true);
this.funcion();
}, child: Text(this.aceptar), color: Colors.white, textColor: Colors.redAccent,)
],
)
],
),
);
}
My issue is that the line of code that should include the function to be posted to the dialog widget :
funcion: SeguidoresCrud().dejarDeSeguir(documentIdSeguidores),
is marked as warning in the editor, the warning message says: Convert to an if element
I guess I am not doing it well, I mean, what I need is to pass a function as parameter to another widget, if possible...
The problem is that you're calling the function, not passing it
Change to:
funcion: () => SeguidoresCrud().dejarDeSeguir(documentIdSeguidores),
This happens because when you pass the function using (), you're actually calling the function and passing it's return value as an argument not the function itself to be called elsewhere
Pass function with () invoking operator
funcion: (){
SeguidoresCrud().dejarDeSeguir(documentIdSeguidores);
},

Flutter - How can I make these Containers to work like a Button?

This is my first App and my first steps in programming. I started with designing the Homepage. Now I want the Containers to act like Buttons, so that I can navigate to other pages. I just can't figure out a way to do so. Maybe u guys got some ideas.
Do i have to delete the 5 Containers and add 5 buttons and redesign them?
I Think there might be a problem since I wrote the buttons as widget?
The Code so far:
//import 'dart:html';
import 'package:apptierpark/Anfahrt.dart';
import 'package:flutter/material.dart';
void main () => runApp(MaterialApp(home: Tierpark()));
class Tierpark extends StatelessWidget {
get assets => null;
get image => null;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(60.0),
child: AppBar(
title: Text('Tierpark Marzahne',
style: TextStyle (
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 45,
fontFamily: 'Amatic',
shadows: [
Shadow(
blurRadius: 10.0,
color: Colors.white,
offset: Offset(5.0, 5.0),
)
]
)),
flexibleSpace: Image(
image: AssetImage('images/urwald4.jpg'),
fit: BoxFit.fill,
),
backgroundColor: Colors.transparent,
),
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(image: AssetImage('images/bamboo.jpg'), fit: BoxFit.fill)),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children:
<Widget>[
MenuButton2('Bewohner',),
SizedBox(height: 50),
MenuButton2('Parkplan'),
SizedBox(height: 40),
MenuButton2('Zeiten & Preise'),
SizedBox(height: 40),
MenuButton2('Anfahrt'),
SizedBox(height: 40),
MenuButton2 ('Über Uns')
]
,)
,)
)
);
}
}
//Button Mainpage Neu
class MenuButton2 extends StatelessWidget {
final String title;
const MenuButton2(this.title);
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: const Color(0xFFa9d470),
border: Border.all(
color: const Color(0xFFa9d470)
),
borderRadius: BorderRadius.all(Radius.circular(20)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.9),
spreadRadius: 10,
blurRadius: 12
)
]
),
width: MediaQuery.of(context).size.height*0.38,
height: MediaQuery.of(context).size.height*0.11,
child: Align(
alignment: Alignment.center,
child: Text (title,
style: TextStyle(
fontSize: 50,
fontFamily: 'Amatic',
fontWeight: FontWeight.bold
),))
);
}
}
Wrap the Container with GestureDetector or InkWell like this and call functions with it's properties,
class MenuButton2 extends StatelessWidget {
final String title;
final int buttonId;
const MenuButton2(this.title,this.buttonId);
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
if(buttonId == 1){
// do 1
}
else if(buttonId == 2){
// do 2
}
else if(buttonId == 3){
// do 3
}
else if(buttonId == 4){
// do 4
}
else {
// do 5
}
},
child:Container(
decoration: BoxDecoration(
color: const Color(0xFFa9d470),
border: Border.all(
color: const Color(0xFFa9d470)
),
borderRadius: BorderRadius.all(Radius.circular(20)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.9),
spreadRadius: 10,
blurRadius: 12
)
]
),
width: MediaQuery.of(context).size.height*0.38,
height: MediaQuery.of(context).size.height*0.11,
child: Align(
alignment: Alignment.center,
child: Text (title,
style: TextStyle(
fontSize: 50,
fontFamily: 'Amatic',
fontWeight: FontWeight.bold
),
),
),
);
}
And in the place where you call the function do this,
...
<Widget>[
MenuButton2('Bewohner', 1),
SizedBox(height: 50),
MenuButton2('Parkplan', 2),
SizedBox(height: 40),
MenuButton2('Zeiten & Preise', 3),
SizedBox(height: 40),
MenuButton2('Anfahrt', 4),
SizedBox(height: 40),
MenuButton2 ('Über Uns', 5)
],
...
Add your Container inside Inkwell or GestureDetector Widgtes refer below code hope its help to you.
Inkwell Widget
GestureDetector Widgets
// GestureDetector( you use GestureDetector also here instead of InkWell Widgets
InkWell(
onTap: () {
print('button Pressed');
// Call your onPressed or onTap function here
},
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.all(
Radius.circular(30),
),
),
height: 50,
width: 200,
child: Text(
'Search',
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
),
),
Your result screen ->

Display a widget if the user is an admin flutter

I have a "settings" screen where the user can click on "Admin mode" and then is asked for a password. If this password corresponds to a defined password that I'll give to the admins of the app, he has the app displaying all the admin widgets on the other screens.
I want to set a default admin password, when the user click on the "validate" button, the program check is the password is correct. I have a button on a screen that is like the "admin panel" and I want this button to be displayed only if the user is an admin.
Here is the Dialog I created and where I suppose I'll have to create something to check if the password is correct in the onPressed function.
class DialogModeAdmin extends StatelessWidget {
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
String _passAdmin;
dialogContent(BuildContext context) {
return Container(
decoration: new BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black26,
blurRadius: 10.0,
offset: const Offset(0.0, 10.0),
),
],
),
child: SizedBox(
height: 120,
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text("Mot de passe"),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: new BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.black,
width: 1,
),
boxShadow: [BoxShadow(
color: Color.fromRGBO(10, 10, 10, 0.25),
blurRadius: 5.0,
spreadRadius: -2.0,
offset: Offset(3.0, 5.0),
)],
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
child: SizedBox(
height: 30,
child: Padding(
padding: const EdgeInsets.only(left: 5.0, right: 5.0, top: 1.0, bottom: 4.0),
child: FormBuilderTextField(
// validator: FormBuilderValidators.required(context),
decoration: InputDecoration(
border: InputBorder.none,
),
name: 'passadmin',
onChanged: (String value) {
_passAdmin = value;
},
),
)
)
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: SizedBox(
height: 30,
width: 90,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Color.fromRGBO(255, 64, 0, 1.0),
onPrimary: Colors.white,
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10.0))),
),
onPressed: () async{
if(_fbKey.currentState.validate()){
// check if the password is correct and then set a local variable to true to set the privileges of an admin
}
},
child: Text('Valider'),
),
),
),
],
)
)
);
}
#override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 0.0,
backgroundColor: Colors.transparent,
child: dialogContent(context),
);
}
}
You can store a isAdmin boolean in a static way or with ChangeNotifier (similar to observable).
https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple
https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html
Then use this value to show/hide your widgets with the Visibility Widget
https://api.flutter.dev/flutter/widgets/Visibility-class.html
Visibility(
visible: // isAdmin variable,
child: ...
),
EDIT : For your problem to check the password :
class DialogModeAdmin extends StatelessWidget {
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
String _passAdmin;
// This is your password
final String _password = "MyPassword";
dialogContent(BuildContext context) {
...
name: 'passadmin',
// Here you store correctly what the user typed
onChanged: (String value) {
_passAdmin = value;
},
),
...
child: ElevatedButton(
...
onPressed: () async{
if(_fbKey.currentState.validate()){
// check if the password is correct and then set a local variable to true to set the privileges of an admin
// As the comment says :
if(_passAdmin == _password){
// set the static/valueNotifier to true
} else {
// display an error 'wrong password'
}
}
},
child: Text('Valider'),
),
...
}