Flutter - Passing Information to custom Button Widget - flutter

I'm trying to make a Custom Button Widget to reuse it in my code.
Within my page I'm calling the button like this:
import 'package:app/components/MyCustomButton.dart';
[...]
const MyCustomButton(
title: 'Title of the button',
type: 'primary'
),
the complete Source of MyCustomButton is below. The Issue I'm having is when displaying Text that was defined in the MyCustomButton.dart file the button works perfectly fine. Now I don't want to display static text but instead text that I am passing from the screen file (e.g.: title variable)
When changing the static text
FROM TO
-------------------------------------------------------------------------------
const Text( -> const Text(
'Login', -> title,
style: TextStyle( -> style: TextStyle(
color: Colors.white, -> color: Colors.white,
fontSize: 20, -> fontSize: 20,
fontWeight: FontWeight.bold, -> fontWeight: FontWeight.bold,
), -> ),
), -> ),
from 'Login' to title (which I want to pass) the ide throws "Not a constant expression" at me, even if I'm changing it to const title. I'm thankful for any explaination on what I'm missing here and what I'm doing wrong.
Thanks a lot!
import 'package:flutter/material.dart';
class MyCustomButton extends StatelessWidget{
final String title;
final String type;
const MyCustomButton({
super.key,
required this.title,
required this.type,
});
#override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.fromLTRB(35, 15, 35, 15),
margin: const EdgeInsets.symmetric(horizontal: 20),
decoration: const BoxDecoration(
color: Color.fromRGBO(112, 143, 164, 1),
borderRadius: BorderRadius.all(Radius.circular(4)),
),
child: const Text(
'Login',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
);
}
}

have you tried removing const from "const Text"?
child: Text(
title,
style: const TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),

You are using super.key . Instead use Key? key.
Also,remove const keyword in your my page.
class MyCustomButton extends StatelessWidget {
final String title;
final String type;
const MyCustomButton({
Key? key,
required this.title,
required this.type,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.fromLTRB(35, 15, 35, 15),
margin: const EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(
color: const Color.fromRGBO(112, 143, 164, 1),
borderRadius: BorderRadius.circular(4),
),
child: Text(
title,
style: const TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
);
}
}

Buuton
class MyCustomButton extends StatelessWidget {
final Function() onTap;
final String title;
final String type;
const MyCustomButton({
super.key,
required this.title,
required this.type,
required this.onTap,
});
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
padding: const EdgeInsets.fromLTRB(35, 15, 35, 15),
margin: const EdgeInsets.symmetric(horizontal: 20),
decoration: const BoxDecoration(
color: Color.fromRGBO(112, 143, 164, 1),
borderRadius: BorderRadius.all(Radius.circular(4)),
),
child: const Text(
'Login',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
);
}
}
Calling
MyCustomButton(title: "title", type: "type", onTap: (){print("object");}),

Related

How to add a TextButton inside ProfileListItem in flutter

how i create a text button inside profile list item?
please check the code and help to create a text button i edited previous code because 2 person said that they need to see my ProfileListItem
i tried to add a TextButton inside ProfileListItem but i can't. here is my code how i create a text
button inside profile list item?
Expanded(
child: ListView(
children: const <Widget>[
ProfileListItem(
icon: LineAwesomeIcons.lock,
text: 'Privacy',
hasNavigation: true,
),
class ProfileListItem extends StatelessWidget {
final IconData icon;
final text;
final bool hasNavigation;
const ProfileListItem({
Key? key,
required this.icon,
this.text,
required this.hasNavigation,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
height: kSpacingUnit.w * 5.5,
margin: EdgeInsets.symmetric(horizontal: kSpacingUnit.w * 4)
.copyWith(bottom: kSpacingUnit.w * 2),
padding: EdgeInsets.symmetric(horizontal: kSpacingUnit.w * 2),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(kSpacingUnit.w * 3),
//color: Theme.of(context).backgroundColor,
color: AppColors.deep_orange,
),
child: Row(children: <Widget>[
Icon(
this.icon,
size: kSpacingUnit.w * 2.5,
),
SizedBox(width: kSpacingUnit.w * 2.5),
Text(
this.text,
style: kTitleTextStyle.copyWith(fontWeight: FontWeight.w500),
),
Row(
children: <Widget>[
Icon(
this.icon,
size: kSpacingUnit.w * 2.5,
),
SizedBox(width: kSpacingUnit.w * 2.5),
Text(
this.text,
style: kTitleTextStyle.copyWith(fontWeight: FontWeight.w500),
),
],
),
]));
}
}
Please try the below code :
class ProfileListItem extends StatelessWidget {
final IconData icon;
final String? text;
final bool hasNavigation;
const ProfileListItem({
Key? key,
required this.icon,
this.text,
required this.hasNavigation,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
height: 10.h,
// margin:
// EdgeInsets.symmetric(horizontal: 10.w * 4).copyWith(bottom: 10 * 2),
// padding: EdgeInsets.symmetric(horizontal: 10.w * 2),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10 * 3),
//color: Theme.of(context).backgroundColor,
color: Colors.deepOrange,
),
child: Row(children: [
TextButton(
onPressed: () {},
child: Text(
text ?? "",
style: const TextStyle(fontSize: 12),
),
),
Expanded(
child: TextButton(
onPressed: () {},
child: Row(
children: <Widget>[
Icon(
icon,
size: 20,
color: Colors.white,
),
Text(
text ?? "",
style: const TextStyle(
fontSize: 12,
color: Colors.white,
),
),
],
),
),
),
]));
}
}
For more detail see here : https://api.flutter.dev/flutter/material/TextButton-class.html

flutter: child isn't defined

I'm having trouble in an attempt to add an child but idk why doesn't work unless something is wrong with my numberform.dart
TextFormField(
controller: numteamController,
validator: (value) {
if (value!.isEmpty) {
return "Enter Valid Number";
} else {
return null;
}
},
child: NumberForm(
text: "Team Number",
formText: "Enter team number",
padding: 0,
)
),
numberform.dart
import 'package:flutter/material.dart';
class NumberForm extends StatelessWidget {
const NumberForm(
{Key? key,
required this.text,
required this.formText,
required this.padding,
required TextFormField child})
: super(key: key);
final String formText;
final String text;
final double padding;
#override
Widget build(BuildContext context) {
return Column(
children: [
SizedBox(
height: padding,
),
Align(
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.only(bottom: 10.0, left: 30),
child: Text(
text,
style: const TextStyle(
fontFamily: "Oxygen",
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 20,
),
),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 10.0, right: 30, left: 30),
child: TextFormField(
decoration: InputDecoration(
labelText: formText,
fillColor: Colors.white,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
borderSide: const BorderSide(),
),
//fillColor: Colors.green
),
keyboardType: TextInputType.number,
style: const TextStyle(
fontFamily: "Poppins",
),
),
),
],
);
}
},
Here you have to know some basic things
TextFormField doesn't have child property.
Why are using TextFormField child in NumberForm if you are not using it.
you can use NumberForm like the below code.
#override
Widget build(BuildContext context) {
return const NumberForm(
text: "Team Number",
formText: "Enter team number",
padding: 0,
);
}
child: NumberForm(
text: "Team Number",
formText: "Enter team number",
padding: 0,
child: TextFormField,//add the textformfield here
)
In the numberForm class you have mentioned that a child is required but in the above codea child is missing. Add a key child:null in the above code.

Flutter : Persist Data

I am building an online shop. I have a counter[-]0[+] next to every product on the home page. I am able to add and remove products to the cart but when I switch to a different screen, my counter on the home page is reset back to 0. I would like to keep that data persistent. what would be the best way to achieve this?
cart_counter.dart
import 'package:flutter/material.dart';
import '../providers/cart.dart';
import 'package:provider/provider.dart';
import '../providers/products.dart';
class CartCounter extends StatefulWidget {
const CartCounter({Key? key}) : super(key: key);
#override
_CartCounterState createState() => _CartCounterState();
}
class _CartCounterState extends State<CartCounter> {
int numOfItems = 0;
#override
Widget build(BuildContext context) {
final product = Provider.of<Product>(context, listen: false);
final cart = Provider.of<Cart>(context, listen: false);
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CounterButton(
icon: Icons.remove,
onPress: () {
if (numOfItems > 0) {
setState(() {
numOfItems--;
});
cart.removeSingleItem(product.id);
}
},
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 13.0),
child: Text(
numOfItems.toString(),
style: const TextStyle(
fontSize: 20.0,
),
),
),
CounterButton(
icon: Icons.add,
onPress: () {
setState(() {
numOfItems++;
cart.addItem(
product.id,
product.price,
product.title,
);
});
},
),
],
);
}
}
class CounterButton extends StatelessWidget {
final IconData icon;
final void Function() onPress;
const CounterButton({
Key? key,
required this.icon,
required this.onPress,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return SizedBox(
width: 60.0,
height: 45.0,
child: OutlinedButton(
style: OutlinedButton.styleFrom(
elevation: 2,
backgroundColor: Theme.of(context).primaryColor,
primary: Theme.of(context).primaryColor,
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
onPressed: onPress,
child: Icon(
icon,
color: Colors.white,
size: 30.0,
),
),
);
}
}
product_item.dart
import 'package:flutter/material.dart';
import 'cart_counter.dart';
class ProductItem extends StatelessWidget {
final String id;
final String title;
final double price;
final String image;
const ProductItem(this.id, this.title, this.price, this.image, {Key? key})
: super(key: key);
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0),
child: Card(
elevation: 2.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Column(
children: [
Row(
children: [
Container(
height: 50,
width: 70.0,
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(20.0),
bottomRight: Radius.circular(20.0),
),
color: Theme.of(context).primaryColor,
),
child: Center(
child: Text(
title,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.0,
color: Colors.white,
),
),
),
),
],
),
Image.asset(image),
const SizedBox(
height: 10.0,
),
Text(
price.toStringAsFixed(2),
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0,
),
),
const SizedBox(
height: 10.0,
),
const CartCounter(),
const SizedBox(
height: 20.0,
),
],
),
),
);
}
}
Use Shared Preferences or Secure Storage to store the values.
See this answer to a similar question.

How to add icon property in button widget using class in flutter

I created a class of RoundedButton and call that class where I want a button. I added all required properties for a button. here is my class
import 'package:flutter/material.dart';
class RoundedButton extends StatelessWidget {
final String text;
final Function press;
final Color color, textColor;
final Icons icon;
const RoundedButton({
Key key,
this.text,
this.press,
this.color = Colors.grey,
this.icon,
this.textColor = Colors.white,
}) : super(key: key);
#override
Widget build(BuildContext context) {
TextStyle style = TextStyle(fontFamily: 'Montserrat', fontSize: 20.0);
return Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(30.0),
color: Color(0xff01A0C7),
child: MaterialButton(
minWidth: MediaQuery.of(context).size.width,
padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: press,
child:Row(
children: <Widget>[
Icon(Icons.icon)),
Text(text,
textAlign: TextAlign.left,
style: style.copyWith(
color: Colors.white, fontWeight: FontWeight.bold)
),
],
)
// child: Text(text,
// textAlign: TextAlign.left,
// style: style.copyWith(
// color: Colors.white, fontWeight: FontWeight.bold)
// ),
),
);
}
}
here it calls look like
RoundedButton(text: "Time out",color: Colors.white,),),
So, when i call this RoundedButton i can change the properties value as required for each button, I want to change icon of buttons too, so my problem is i am not accessing icon variable on Icon(Icons.icon).
Kindly please help how to do this.
Just change the final Icons icon to the final Icon icon
and replace Icon(Icons.icon) with icon
to be like this :
import 'package:flutter/material.dart';
class RoundedButton extends StatelessWidget {
final String text;
final Function press;
final Color color, textColor;
final Icon icon;
const RoundedButton({
Key key,
this.text,
this.press,
this.color = Colors.grey,
this.icon = const Icon(Icons.ac_unit),
this.textColor = Colors.white,
}) : super(key: key);
#override
Widget build(BuildContext context) {
TextStyle style = TextStyle(fontFamily: 'Montserrat', fontSize: 20.0);
return Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(30.0),
color: Color(0xff01A0C7),
child: MaterialButton(
minWidth: MediaQuery.of(context).size.width,
padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: press,
child: Row(
children: <Widget>[
icon,
Text(text,
textAlign: TextAlign.left,
style: style.copyWith(
color: Colors.white, fontWeight: FontWeight.bold)),
],
)
// child: Text(text,
// textAlign: TextAlign.left,
// style: style.copyWith(
// color: Colors.white, fontWeight: FontWeight.bold)
// ),
),
);
}
}
Solution
Just added this statement icon == null ? Container() : icon, on Amin Al-jebbeh solution
import 'package:flutter/material.dart';
//import 'package:attendance_system_app/new.dart';
class RoundedButton extends StatelessWidget {
final String text;
final Function press;
final Color color, textColor;
final Icon icon;
const RoundedButton({
Key key,
this.text,
this.press,
this.color = Colors.grey,
this.icon,
this.textColor = Colors.white,
}) : super(key: key);
#override
Widget build(BuildContext context) {
TextStyle style = TextStyle(fontFamily: 'Montserrat', fontSize: 20.0);
return Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(30.0),
color: Color(0xff01A0C7),
child: MaterialButton(
minWidth: MediaQuery.of(context).size.width,
padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: press,
child:Row(
children: <Widget>[
icon == null ? Container() :
icon,
Text(text,
textAlign: TextAlign.left,
style: style.copyWith(
color: Colors.white, fontWeight: FontWeight.bold)
),
],
)
// child: Text(text,
// textAlign: TextAlign.left,
// style: style.copyWith(
// color: Colors.white, fontWeight: FontWeight.bold)
// ),
),
);
}
}

How to get value from a list of values in flutter

I have three containers with different information(Strings and Icon) in each and that I want to put in a column.
I want to get the value of the clicked one and want to change the color of the container when clicked, how can I do that, please?
Also, I want to get the value of the strings selected
I think it's simple but I seem not to find a way to do that.
This is my Container widget:
class VisitTypeFees extends StatelessWidget {
const VisitTypeFees({
Key key,
this.onSelected = false,
this.title,
this.subTitle,
this.amount,
this.icon,
}) : super(key: key);
final bool onSelected;
final String title, subTitle, amount;
final IconData icon;
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {},
child: Container(
height: getProportionateScreenHeight(65),
width: SizeConfig.screenWidth - 20,
padding: EdgeInsets.symmetric(
horizontal: getProportionateScreenWidth(10),
vertical: getProportionateScreenWidth(7.5),
),
decoration: BoxDecoration(
color: onSelected ? kSecondaryColor : Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [kDefaultShadow]
),
child: Row(
children: [
Container(
height: getProportionateScreenHeight(50),
width: getProportionateScreenHeight(50),
decoration: BoxDecoration(
color: onSelected
? Colors.white
: kPrimaryLightColor.withOpacity(0.6),
borderRadius: BorderRadius.circular(10)),
child: Icon(
icon,
color: onSelected ? kSecondaryColor : kPrimaryColor,
),
),
SizedBox(
width: getProportionateScreenWidth(7.5),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
title,
style: TextStyle(
color: onSelected ? Colors.white : Colors.black,
fontSize: getProportionateScreenWidth(15),
fontWeight: FontWeight.w600),
),
Text(
subTitle,
style: TextStyle(
color: onSelected ? Colors.white : kTextColor,
fontSize: getProportionateScreenWidth(12),
fontWeight: FontWeight.w500),
),
],
),
Spacer(),
Text(
amount,
style: TextStyle(
color: onSelected ? Colors.white : kPrimaryColor,
fontSize: getProportionateScreenWidth(15),
fontWeight: FontWeight.bold),
),
],
),
),
);
}
}
At first, you need to convert your widget to a StatefulWidget. Then, you need to wrap with InkWell widget for each Text and Icon widget. And they will all have isSelected properties themselves.
It will look like this:
class VisitTypeFees extends StatefulWidget {
const VisitTypeFees({
Key key,
this.onSelected = false,
this.title,
this.subTitle,
this.amount,
this.icon,
}) : super(key: key);
final bool onSelected;
final String title, subTitle, amount;
final IconData icon;
#override
_VisitTypeFeesState createState() => _VisitTypeFeesState();
}
class _VisitTypeFeesState extends State<VisitTypeFees> {
bool iconSelected;
bool firstTextSelected;
bool seccondTextSelected;
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {},
child: Container(
height: getProportionateScreenHeight(65),
width: SizeConfig.screenWidth - 20,
padding: EdgeInsets.symmetric(
horizontal: getProportionateScreenWidth(10),
vertical: getProportionateScreenWidth(7.5),
),
decoration: BoxDecoration(
color: widget.onSelected ? kSecondaryColor : Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [kDefaultShadow]),
child: Row(
children: [
InkWell(
onTap: () {
// icon selected!
setState(() {
iconSelected = true;
firstTextSelected = false;
seccondTextSelected = false;
});
},
child: Container(
height: getProportionateScreenHeight(50),
width: getProportionateScreenHeight(50),
decoration: BoxDecoration(
color: widget.onSelected
? Colors.white
: kPrimaryLightColor.withOpacity(0.6),
borderRadius: BorderRadius.circular(10)),
child: Icon(
widget.icon,
color: widget.onSelected ? kSecondaryColor : kPrimaryColor,
),
),
),
SizedBox(
width: getProportionateScreenWidth(7.5),
),
InkWell(
onTap: () {
// first text - title and subtitle selected!
setState(() {
iconSelected = false;
firstTextSelected = true;
seccondTextSelected = false;
});
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
widget.title,
style: TextStyle(
color: widget.onSelected ? Colors.white : Colors.black,
fontSize: getProportionateScreenWidth(15),
fontWeight: FontWeight.w600),
),
Text(
widget.subTitle,
style: TextStyle(
color: widget.onSelected ? Colors.white : kTextColor,
fontSize: getProportionateScreenWidth(12),
fontWeight: FontWeight.w500),
),
],
),
),
Spacer(),
InkWell(
onTap: () {
// second text - amount selected.
setState(() {
iconSelected = false;
firstTextSelected = false;
seccondTextSelected = true;
});
},
child: Text(
widget.amount,
style: TextStyle(
color: widget.onSelected ? Colors.white : kPrimaryColor,
fontSize: getProportionateScreenWidth(15),
fontWeight: FontWeight.bold),
),
),
],
),
),
);
}
}