Error: The method 'raisedButton' isn't defined for the class '_PomodoroState' - flutter

I'm currently doing a flutter tutorial in android studio and I have this issue,
I tried to create a class, tried to become it a variable, but no luck, also I named a file “raised_button.dart” and use the stful widget to see if it works but it doesn't work
This is my code:
import 'package:flutter/material.dart';
import 'package:percent_indicator/circular_percent_indicator.dart';
import 'dart:async';
void main() => runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: Pomodoro(),
));
class Pomodoro extends StatefulWidget {
const Pomodoro({Key? key}) : super(key: key);
#override
State<Pomodoro> createState() => _PomodoroState();
}
class _PomodoroState extends State<Pomodoro> {
double percent = 0;
static int TimeInMinut = 240;
int TimeInSec = TimeInMinut * 60;
late Timer timer;
_StartTimer(){
TimeInMinut = 240;
int Time = TimeInMinut *60;
double SecPercent = (Time/100);
timer = Timer.periodic(Duration(seconds:1), (timer) {
setState((){
if(Time > 0){
Time--;
if(Time % 60 ==0){
TimeInMinut --;
}if(Time % SecPercent == 0){
if(percent <1){
percent += 0.01;
}else{
percent = 1;
}
}
}else{
percent = 0;
TimeInMinut = 240;
timer.cancel();
}
});
});
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.orangeAccent, Colors.redAccent],
begin: FractionalOffset(0.5,1)
)
),
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 25.0),
child: Text(
"Pomodoro Clock",
style: TextStyle(
color: Colors.white,
fontSize: 40.0
),
),
),
Expanded(
child: CircularPercentIndicator(
percent: percent,
animation: true,
animateFromLastPercent: true,
radius: 150.0,
lineWidth: 20.0,
progressColor: Colors.white,
center: Text(
"$TimeInMinut",
style: TextStyle(
color: Colors.white,
fontSize: 80.0
),
),
),
),
SizedBox(height: 10.0,),
Expanded(
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topRight: Radius.circular(30.0),topLeft: Radius.circular(30.0))
),
child: Padding(
padding: EdgeInsets.only(top: 30.0, left: 20.0, right: 20.0),
child: Column(
children: <Widget>[
Expanded(
child: Row(
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
Text(
"Focus Time",
style: TextStyle(
fontSize: 20.0,
),
),
SizedBox(height: 10.0,),
Text(
"240",
style: TextStyle(
fontSize: 50.0
),
),
]
),
),
Expanded(
child: Column(
children: <Widget>[
Text(
"Pause Time",
style: TextStyle(
fontSize: 20.0,
),
),
SizedBox(height: 10.0,),
Text(
"20",
style: TextStyle(
fontSize: 50.0
),
),
]
),
)
],
)
),
Padding(
padding: EdgeInsets.symmetric(vertical: 28.0),
child: raisedButton(
onPressed: _StartTimer,
color: Colors.redAccent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100.0),
),
child: Padding(
padding: EdgeInsets.all(20.0),
child: Text("Start focusing",
style: TextStyle(
color: Colors.white,
fontSize: 22.0
),
),
)
),
)
],
)
),
),
),
],
),
),
),
);
}
}
and this what is shows on terminal
lib/main.dart:151:38: Error: The method 'raisedButton' isn't defined for the class '_PomodoroState'.
- '_PomodoroState' is from 'package:pomodoris/main.dart' ('lib/main.dart').
Try correcting the name to the name of an existing method, or defining a method named 'raisedButton'.
child: raisedButton(
What should I do in that particular case?
Thank you in advance.

Capitalize the R. It's RaisedButton, not raisedButton.
However, RaisedButton is depricated. Instead of
raisedButton(
onPressed: _StartTimer,
color: Colors.redAccent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100.0),
),
child: Padding(
you want to use ElevatedButton. You also need to move your styling to the new style property, where you pass the color etc. into ElevatedButton.styleFrom() constructor.
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100.0),
),
),
onPressed: _StartTimer,
child: Padding(
However...
This look is also depricated according to the Material Guidelines that Flutter follows. See how to make buttons look nice and modern here: https://material.io/components/buttons
All of the names are also the names of the widgets in Flutter. If you get stuck there, feel free to ask again!

**RaisedButton is deprecated on the Latest flutter version. You can replace RaisedButton with ElevatedButton **
ElevatedButton(
child: Text('ElevatedButton'))

RaisedButton is no longer use by Flutter new versions
instead you can use an Elevated button
ElevatedButton(
onPressed: () {
print('login clicked');
},
child: Text(
'Login',
style: TextStyle(fontSize: 18.0, fontFamily: "Brand Bold"),
))

Related

How do i correctly initialise a variable from a stateful widget to another widget in flutter and maintain state?

I have two widgets
JobsHeaderWidget
JobsView
JobsHeaderWidget is a stateful widget where i code all the logic and initialise int current = 0; in the state. In this same file, i have another class named CategoriesBuilder where i use switch cases to make sure at each switch case a different container is returned. ( a switch case for each tab )
This switch cases is now responsible for switching containers depending on the tab bar selected as seen in this image:
I will also drop the code snippet of the JobsHeaderWidget for better clarifications.
The problem is - when i use this CategoriesBuilder in same widget as the 'JobsHeaderWidget' it works.
But i don't want to use it in same widget cos of the logic of my design. I want to be able to use this builder in JobsView widget which is another dart file and it doesn't work maybe because of wrong approach.
I tried converting the JobsView to a stateful widget and initialising 'int current = 0;' but it doesn't work.
I also tried making int current = 0; global var, it worked but the state doesn't change when i select individual tab bars. ( I mean my switch cases don't seem to work ).
I have gone round stackoverflow for answers before asking this but can't find a solution.
Snippets of each widgets below.
JobsHeaderWidget
class JobsHeaderWidget extends StatefulWidget {
const JobsHeaderWidget({
Key key,
}) : super(key: key);
#override
State<JobsHeaderWidget> createState() => _JobsHeaderWidgetState();
}
class _JobsHeaderWidgetState extends State<JobsHeaderWidget> {
List<String> items = [
"All",
"Critical",
"Open",
"Closed",
"Overdue",
];
ValueChanged<int> onChange;
int current = 0;
List<DropdownMenuItem<String>> get dropdownItems {
List<DropdownMenuItem<String>> menuItems = [
DropdownMenuItem(
child: Text(
"Today",
),
value: "Today"),
];
return menuItems;
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 15.0, right: 15.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Jobs',
style: GoogleFonts.poppins(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.w600),
),
Row(
children: [
Text(
'View Insights ',
style: GoogleFonts.poppins(
color: Color(0xff3498DB),
fontSize: 12,
fontWeight: FontWeight.w500),
),
Icon(
Icons.arrow_forward_ios,
color: Color(0xff3498DB),
size: 12,
),
],
),
SizedBox(
height: 10,
),
filterJobs(),
],
),
),
);
}
Widget filterJobs() {
String selectedValue = "Today";
return Column(
children: [
Container(
constraints: const BoxConstraints(maxWidth: 600, maxHeight: 100),
width: double.infinity,
child: IntrinsicWidth(
child: FittedBox(
fit: BoxFit.fitWidth,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
for (int i = 0; i < items.length; i++) ...[
GestureDetector(
onTap: () {
setState(() {
current = i;
});
},
child: AnimatedContainer(
height: 40,
duration: const Duration(milliseconds: 300),
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.only(
left: 14.0, right: 14.0, top: 4, bottom: 4),
decoration: BoxDecoration(
color: current == i
? const Color(0xff34495E)
: const Color(0xffF5F5F5),
borderRadius: BorderRadius.circular(50),
),
child: Center(
child: Text(
items[i],
style: GoogleFonts.poppins(
fontSize: 15,
fontWeight: FontWeight.w500,
color:
current == i ? Colors.white : Colors.grey),
),
),
),
),
]
],
),
),
),
),
Divider(
color: Color(0xff34495E).withOpacity(0.2),
),
Row(
children: [
Text(
'All Jobs',
style:
GoogleFonts.poppins(fontSize: 9, fontWeight: FontWeight.w400),
),
SizedBox(
width: 5,
),
Text(
' * This Week',
style:
GoogleFonts.poppins(fontSize: 9, fontWeight: FontWeight.w400),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'25',
style: GoogleFonts.poppins(
fontSize: 20, fontWeight: FontWeight.w600),
),
Container(
height: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(2),
color: Color(0xffF4F4F4)),
child: Padding(
padding: const EdgeInsets.only(
left: 8.0,
),
child: Row(
children: [
Container(
decoration: BoxDecoration(
color: Color(0xff34495E),
borderRadius: BorderRadius.circular(2)),
child: Icon(
Icons.tune,
size: 15,
color: Colors.white,
),
),
SizedBox(
width: 5,
),
DropdownMenuItem(
child: DropdownButtonHideUnderline(
child: Container(
child: DropdownButton(
isDense: true,
style: GoogleFonts.poppins(
fontSize: 10,
fontWeight: FontWeight.w500,
color: Color(0xff34495E),
),
onChanged: (value) {},
items: dropdownItems,
value: selectedValue,
),
),
),
),
],
),
),
),
],
),
//If i uncomment this line and use the category builder here, it works fine! CategoriesBuilder(current: current)
],
);
}
}
class CategoriesBuilder extends StatelessWidget {
const CategoriesBuilder({
Key key,
#required this.current,
}) : super(key: key);
final int current;
#override
Widget build(BuildContext context) {
return Builder(
builder: (context) {
switch (current) {
case 0:
return AllJobsListView();
case 1:
return CriticalJobsListView();
case 2:
return OpenJobsListView();
case 3:
return ClosedJobsListView();
case 4:
return OverdueJobsListView();
default:
return SizedBox.shrink();
}
},
);
}
}
JobsView
class JobsView extends StatefulWidget {
const JobsView({
Key key,
}) : super(key: key);
#override
State<JobsView> createState() => _JobsViewState();
}
class _JobsViewState extends State<JobsView> {
int current = 0;
#override
Widget build(BuildContext context) {
final controller = Get.put(EServicesController());
return Scaffold(
// floatingActionButton: new FloatingActionButton(
// child: new Icon(Icons.add, size: 32, color: Get.theme.primaryColor),
// onPressed: () => {Get.offAndToNamed(Routes.E_SERVICE_FORM)},
// backgroundColor: Get.theme.colorScheme.secondary,
// ),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
body: RefreshIndicator(
onRefresh: () async {
Get.find<LaravelApiClient>().forceRefresh();
controller.refreshEServices(showMessage: true);
Get.find<LaravelApiClient>().unForceRefresh();
},
child: CustomScrollView(
controller: controller.scrollController,
physics: AlwaysScrollableScrollPhysics(),
shrinkWrap: false,
slivers: <Widget>[
SliverAppBar(
backgroundColor: Color(0xffFFFFFF),
expandedHeight: MediaQuery.of(context).size.height * 0.4,
elevation: 0.5,
primary: true,
pinned: false,
floating: false,
//iconTheme: IconThemeData(color: Get.theme.primaryColor),
// title: Text(
// "Jobs".tr,
// style: Get.textTheme.headline6
// .merge(TextStyle(color: Get.theme.primaryColor)),
// ),
centerTitle: false,
automaticallyImplyLeading: false,
// leading: new IconButton(
// icon: new Icon(Icons.arrow_back_ios,
// color: Get.theme.primaryColor),
// onPressed: () => {Get.back()},
// ),
actions: [
SearchButtonWidget(),
],
//bottom: HomeSearchBarWidget(),
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.parallax,
title: JobsHeaderWidget(),
)),
SliverToBoxAdapter(
child: Wrap(
children: [
//ServicesListWidget(),
// The state doesnt change here for some reasosns CategoriesBuilder(current: current)
],
),
),
],
),
),
);
}
}
Try this: keep your 'int current' within _JobsViewState as you have in your code.
When you call your JobsHeaderWidget , pass the function it will use to update the the value of the current variable; and rebuild the state from here.
Something like this:
class JobsHeaderWidget extends StatefulWidget {
final Function changeCurrentValue(int newValue);
const JobsHeaderWidget({
this.changeCurrentValue,
Key key,
}) : super(key: key);
#override
State<JobsHeaderWidget> createState() => _JobsHeaderWidgetState();
}
class _JobsHeaderWidgetState extends State<JobsHeaderWidget> {
#override
Widget build(BuildContext context) {
// Somewhere inside build, instead calling setState()
// call the function you passed to the widget
GestureDetector(
onTap: () {
changeCurrentValue(i);
},
)
}
}
class _JobsViewState extends State<JobsView> {
int current = 0;
void changeCurrentValue(int newValue) {
setState(() {
current = newValue;
});
}
#override
Widget build(BuildContext context) {
//somewhere inside build
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.parallax,
title: JobsHeaderWidget(changeCurrentValue: changeCurrentValue),
)),
}
}
After hours and even sleeping overnight on this question i came up with a work-around that works. (minor refactoring)
This was my approach :
Convert my JobsView widget to a stateful widget and put all my controllers in place.
Copied all my variables from JobHeaderWidget and put it in the state of my JobsView widget.
Instead of returning a widget in the title of my sliver app as thus :
flexibleSpace: FlexibleSpaceBar( collapseMode: CollapseMode.parallax, title: JobsHeaderWidget(), )),
I copied all of my code from the widget tree from JobsHeaderWidget and put converted to a method and replaced it in my title.
My builder CategoryBuilder was put in a separate then imported as i used it in my SliverAppAdapter .
Of cos i got rid of the unnecessary dart file JobsHeaderWidget.
FULL CODE BELOW
class JobsView extends StatefulWidget {
#override
State<JobsView> createState() => _JobsViewState();
}
class _JobsViewState extends State<JobsView> {
List<String> items = [
"All",
"Critical",
"Open",
"Closed",
"Overdue",
];
int current = 0;
List<DropdownMenuItem<String>> get dropdownItems {
List<DropdownMenuItem<String>> menuItems = [
DropdownMenuItem(
child: Text(
"Today",
),
value: "Today"),
];
return menuItems;
}
#override
Widget build(BuildContext context) {
final controller = Get.put(EServicesController());
return Scaffold(
// floatingActionButton: new FloatingActionButton(
// child: new Icon(Icons.add, size: 32, color: Get.theme.primaryColor),
// onPressed: () => {Get.offAndToNamed(Routes.E_SERVICE_FORM)},
// backgroundColor: Get.theme.colorScheme.secondary,
// ),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
body: RefreshIndicator(
onRefresh: () async {
Get.find<LaravelApiClient>().forceRefresh();
controller.refreshEServices(showMessage: true);
Get.find<LaravelApiClient>().unForceRefresh();
},
child: CustomScrollView(
controller: controller.scrollController,
physics: AlwaysScrollableScrollPhysics(),
shrinkWrap: false,
slivers: <Widget>[
SliverAppBar(
backgroundColor: Color(0xffFFFFFF),
expandedHeight: MediaQuery.of(context).size.height * 0.4,
elevation: 0.5,
primary: true,
pinned: false,
floating: false,
//iconTheme: IconThemeData(color: Get.theme.primaryColor),
// title: Text(
// "Jobs".tr,
// style: Get.textTheme.headline6
// .merge(TextStyle(color: Get.theme.primaryColor)),
// ),
centerTitle: false,
automaticallyImplyLeading: false,
// leading: new IconButton(
// icon: new Icon(Icons.arrow_back_ios,
// color: Get.theme.primaryColor),
// onPressed: () => {Get.back()},
// ),
actions: [
SearchButtonWidget(),
],
//bottom: HomeSearchBarWidget(),
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.parallax,
title: mainHeader(),
)),
SliverToBoxAdapter(
child: Wrap(
children: [
//ServicesListWidget(),
CategoriesBuilder(current: current)
],
),
),
],
),
),
);
}
Padding mainHeader() {
return Padding(
padding: const EdgeInsets.only(left: 15.0, right: 15.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Jobs',
style: GoogleFonts.poppins(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.w600),
),
Row(
children: [
Text(
'View Insights ',
style: GoogleFonts.poppins(
color: Color(0xff3498DB),
fontSize: 12,
fontWeight: FontWeight.w500),
),
Icon(
Icons.arrow_forward_ios,
color: Color(0xff3498DB),
size: 12,
),
],
),
SizedBox(
height: 10,
),
() {
String selectedValue = "Today";
return Column(
children: [
Container(
constraints:
const BoxConstraints(maxWidth: 600, maxHeight: 100),
width: double.infinity,
child: IntrinsicWidth(
child: FittedBox(
fit: BoxFit.fitWidth,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
for (int i = 0; i < items.length; i++) ...[
GestureDetector(
onTap: () {
setState(() {
current = i;
});
},
child: AnimatedContainer(
height: 40,
duration: const Duration(milliseconds: 300),
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.only(
left: 14.0,
right: 14.0,
top: 4,
bottom: 4),
decoration: BoxDecoration(
color: current == i
? const Color(0xff34495E)
: const Color(0xffF5F5F5),
borderRadius: BorderRadius.circular(50),
),
child: Center(
child: Text(
items[i],
style: GoogleFonts.poppins(
fontSize: 15,
fontWeight: FontWeight.w500,
color: current == i
? Colors.white
: Colors.grey),
),
),
),
),
]
],
),
),
),
),
Divider(
color: Color(0xff34495E).withOpacity(0.2),
),
Row(
children: [
Text(
'All Jobs',
style: GoogleFonts.poppins(
fontSize: 9, fontWeight: FontWeight.w400),
),
SizedBox(
width: 5,
),
Text(
' * This Week',
style: GoogleFonts.poppins(
fontSize: 9, fontWeight: FontWeight.w400),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'25',
style: GoogleFonts.poppins(
fontSize: 20, fontWeight: FontWeight.w600),
),
Container(
height: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(2),
color: Color(0xffF4F4F4)),
child: Padding(
padding: const EdgeInsets.only(
left: 8.0,
),
child: Row(
children: [
Container(
decoration: BoxDecoration(
color: Color(0xff34495E),
borderRadius: BorderRadius.circular(2)),
child: Icon(
Icons.tune,
size: 15,
color: Colors.white,
),
),
SizedBox(
width: 5,
),
DropdownMenuItem(
child: DropdownButtonHideUnderline(
child: Container(
child: DropdownButton(
isDense: true,
style: GoogleFonts.poppins(
fontSize: 10,
fontWeight: FontWeight.w500,
color: Color(0xff34495E),
),
onChanged: (value) {},
items: dropdownItems,
value: selectedValue,
),
),
),
),
],
),
),
),
],
),
//CategoriesBuilder(current: current)
],
);
}(),
],
),
),
);
}
}

Dynamically adjust text size in buttons inside Row

I am using localization to support multiple languages in my app. This results in having text in buttons with different length. So I need to have it being responsive.
I have two buttons in a Row(). I want to adjust the textsize inside these buttons so they never produce any overflow. Currently it looks like this in some languages:
I tried using auto_size_text with no success.
This is my code for the dialog:
return Dialog(
backgroundColor: Colors.transparent,
elevation: 0,
child: InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: kIsWeb ? 40.w : 100.w,
color: Theme.of(context).dialogBackgroundColor,
padding: EdgeInsets.all(15.sp),
child: Column(children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
OutlinedButton(
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
side: BorderSide(width: 2, color: Theme.of(context).primaryColor),
primary: Colors.black54),
onPressed: () {
Navigator.of(context).pop();
},
child: Text(AppLocalizations.of(context)!.joinGameDialogCancelButton,
style: TextStyle(fontSize: kIsWeb ? 4.sp : 12.sp)),
),
ElevatedButton(
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
backgroundColor: Theme.of(context).primaryColor,
primary: Colors.white),
onPressed: () async {
if (formKey.currentState!.validate()) {
Navigator.of(context).pop();
widget.onFinished(nameController.text.trim());
}
},
child: AutoSizeText(
AppLocalizations.of(context)!.joinGameDialogJoinButton,
style: TextStyle(fontSize: kIsWeb ? 4.sp : 14.sp),
overflow: TextOverflow.clip,
stepGranularity: 1,
maxLines: 1,
)
),
],
),
Padding(padding: EdgeInsets.only(top: 15.sp)),
Text("some eula text"),
]))
],
),
)));
You can use FittedBox Widget
FittedBox(
fit: BoxFit.scaleDown,
child: Text(
"Your Text Here",
maxLines: 1,
),
),
You can use TextPainter combined without layoutBuilder to determine if the text has overflowed or not, then dynamically resize the text to fit.
Wrapping in a layoutBuilder will determine how much space is available. The textPainter will simulate the rendering of the text and tell you if it has overflowed.
You can save your text size in a variable within the widget state, then decrement the textSize and call setState until the text fits.
See this similar question: How to check if Flutter Text widget was overflowed
Ok, here's what I used: I do not have a mobile device to test it, so I used Windows (but I guess this should not be a problem). In this way, the text gets cut off instead of getting an overflow when it can't get smaller:
return Dialog(
backgroundColor: Colors.transparent,
elevation: 0,
child: InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
//width: 100,
color: Theme.of(context).dialogBackgroundColor,
padding: const EdgeInsets.all(15),
child: Column(children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
OutlinedButton(
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
side: BorderSide(width: 2, color: Theme.of(context).primaryColor),
primary: Colors.black54),
onPressed: () {
Navigator.of(context).pop();
},
child: const Text("weerwerewrweee", style: TextStyle(fontSize: 12)),
),
Expanded(
child: ElevatedButton(
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
backgroundColor: Theme.of(context).primaryColor,
primary: Colors.white),
onPressed: () async {
// if (formKey.currentState!.validate()) {
// Navigator.of(context).pop();
// widget.onFinished(nameController.text.trim());
// }
},
child: const AutoSizeText(
"AppLocalizations.of(context)!.joinGameDialogJoinButton,",
style: TextStyle(fontSize: 14),
overflow: TextOverflow.clip,
stepGranularity: 1,
minFontSize: 1,
maxLines: 1,
)),
),
],
),
const Padding(padding: EdgeInsets.only(top: 15)),
const Text("some eula text"),
]))
],
),
)));
The difference with the original code should be only these:
I removed the container width because on Windows it was really too small to test
I wrapped the ElevatedButton in an Expanded following some auto_size_text suggestion
I changed the minFontSize to 1 (obviously too low, but useful for testing)
I put some random texts in the buttons, leaving the second one very long
I removed the onPressed argument just for testing
This is what I got:
big window
small window
The minimum font size must be adjusted, but I think that there's no way to have a readable text AND having maxLines: 1. You probably must choose one of them, or settle for a very small text.
EDIT:
here's how it looks with maxLines: 2:
EDIT 2:
The trick using an empty Expanded to keep the button separated and avoiding a full-width second button:
[...]
const Expanded(child: Text('')),
Expanded(
child: ElevatedButton(
[...]
Result, with short text in the second button:
Please look into the answer i have added spacer() for in between space
Dialog(
backgroundColor: Colors.transparent,
elevation: 0,
child: InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
//width: 100,
color: Theme.of(context).dialogBackgroundColor,
padding: const EdgeInsets.all(15),
child: Column(children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
OutlinedButton(
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
side: BorderSide(width: 2, color: Theme.of(context).primaryColor),
primary: Colors.black54),
onPressed: () {
Navigator.of(context).pop();
},
child: const Text("weerwerewrweee", style: TextStyle(fontSize: 12)),
),
Spacer(),
Expanded(
flex: 3,
child: ElevatedButton(
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
backgroundColor: Theme.of(context).primaryColor,
primary: Colors.white),
onPressed: () async {
// if (formKey.currentState!.validate()) {
// Navigator.of(context).pop();
// widget.onFinished(nameController.text.trim());
// }
},
child: const Text(
"TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest",
style: TextStyle(fontSize: 14),
overflow: TextOverflow.clip,
)),
),
],
),
const Padding(padding: EdgeInsets.only(top: 15)),
const Text("some eula text"),
]))
],
),
)))
SizedBox is used for this condition only.
You can use sizedbox to size any of the Widget.
In your case,
Try with this code -
class CustomButton extends StatelessWidget {
CustomButton();
#override
Widget build(BuildContext context) {
return Dialog(
backgroundColor: Colors.transparent,
elevation: 0,
child: InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 200,
color: Theme.of(context).dialogBackgroundColor,
padding: EdgeInsets.all(5),
child: Column(children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: 80,
child: OutlinedButton(
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(20.0)),
side: BorderSide(
width: 2,
color: Theme.of(context).primaryColor),
primary: Colors.black54),
onPressed: () {
Navigator.of(context).pop();
},
child: Text("Raushan is flutter developer",
style: TextStyle(fontSize: 12)),
),
),
SizedBox(
width: 80,
child: ElevatedButton(
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(20.0)),
backgroundColor:
Theme.of(context).primaryColor,
primary: Colors.white),
onPressed: () async {},
child: Text("Raushan is flutter developer",
style: TextStyle(fontSize: 12)),
),
)
],
),
Padding(padding: EdgeInsets.only(top: 15)),
Text("some eula text"),
]))
],
),
)));
}
}
I think this will fix your issue.
No need of using any dependency
Use custom class AdaptableText in your project.
adaptable_text.dart
import 'package:flutter/cupertino.dart';
class AdaptableText extends StatelessWidget {
final String text;
final TextStyle? style;
final TextAlign textAlign;
final TextDirection textDirection;
final double minimumFontScale;
final TextOverflow textOverflow;
const AdaptableText(this.text,
{this.style,
this.textAlign = TextAlign.left,
this.textDirection = TextDirection.ltr,
this.minimumFontScale = 0.5,
this.textOverflow = TextOverflow.ellipsis,
Key? key})
: super(key: key);
#override
Widget build(BuildContext context) {
TextPainter _painter = TextPainter(
text: TextSpan(text: this.text, style: this.style),
textAlign: this.textAlign,
textScaleFactor: 1,
maxLines: 100,
textDirection: this.textDirection);
return LayoutBuilder(
builder: (context, constraints) {
_painter.layout(maxWidth: constraints.maxWidth);
double textScaleFactor = 1;
if (_painter.height > constraints.maxHeight) { //
print('${_painter.size}');
_painter.textScaleFactor = minimumFontScale;
_painter.layout(maxWidth: constraints.maxWidth);
print('${_painter.size}');
if (_painter.height > constraints.maxHeight) { //
//even minimum does not fit render it with minimum size
print("Using minimum set font");
textScaleFactor = minimumFontScale;
} else if (minimumFontScale < 1) {
//binary search for valid Scale factor
int h = 100;
int l = (minimumFontScale * 100).toInt();
while (h > l) {
int mid = (l + (h - l) / 2).toInt();
double newScale = mid.toDouble()/100.0;
_painter.textScaleFactor = newScale;
_painter.layout(maxWidth: constraints.maxWidth);
if (_painter.height > constraints.maxHeight) { //
h = mid - 1;
} else {
l = mid + 1;
}
if (h <= l) {
print('${_painter.size}');
textScaleFactor = newScale - 0.01;
_painter.textScaleFactor = newScale;
_painter.layout(maxWidth: constraints.maxWidth);
break;
}
}
}
}
return Text(
this.text,
style: this.style,
textAlign: this.textAlign,
textDirection: this.textDirection,
textScaleFactor: textScaleFactor,
maxLines: 100,
overflow: textOverflow,
);
},
);
}
}
Now use this class
Container(
width: 250,
height: 20,
color: Colors.green,
child: AdaptableText(mediumSizeText, style: const TextStyle()),
),
Here i am also showing the difference between normal text, text inside size box and adaptive text
return Scaffold(
appBar: AppBar(
title: const Text('ExpandableText'),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Text('Normal Text'),
Text(mediumSizeText),
const SizedBox(
height: 20,
),
const Text('Container(250*20) Normal Text:'),
Container(
width: 250,
height: 20,
color: Colors.green,
child: Text(
mediumSizeText,
overflow: TextOverflow.ellipsis,
),
),
const SizedBox(
height: 20,
),
const Text('Container(250*20) => sizebox => Text:'),
Container(
width: 250,
height: 20,
color: Colors.green,
child: FittedBox(
fit: BoxFit.fitWidth,
child: Text(
mediumSizeText,
maxLines: 100,
),
),
),
const Text('Container(250*20) => AdaptableText => Text:'),
Container(
width: 250,
height: 20,
color: Colors.green,
child: AdaptableText(mediumSizeText, style: const TextStyle()),
),
],
),
);
Here is the result:

Multiple Selection of ListTile

I am new to Flutter here i'm trying to select all the square boxes, given below is the code for single selection of ListTile when one tile is selected it changes it's background color to redAccent, but i need code for multiple selection where i can select all three ListTile or either two ListTile and not only one
class MultiSelect extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: GradientAppBar(
title: Text('MultiSelect'),
),
body: MultipleSelectItems(),
);
}
}
class MultipleSelectItems extends StatefulWidget {
#override
_MultipleSelectItemsState createState() => _MultipleSelectItemsState();
}
class _MultipleSelectItemsState extends State<MultipleSelectItems> {
String selected = "First";
#override
Widget build(BuildContext context) {
return Container(
child: GestureDetector(
child: Column(
children: <Widget>[
SizedBox(
height: 40,
),
GestureDetector(
onTap: () {
setState(() {
selected = "First";
});
},
child: Container(
margin: EdgeInsets.only(left: 15, right: 15),
height:100,
width: double.maxFinite,
decoration: BoxDecoration(
color: selected == 'First' ? Colors.redAccent : Colors.lightBlueAccent,
),
child: ListTile(
title: Text(
'First',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontFamily: 'WorksSansSemiBold',
fontWeight: FontWeight.bold,
),
),
),
),
),
Padding(padding: EdgeInsets.only(top: 20)),
GestureDetector(
onTap: () {
setState(() {
selected = "Second";
});
},
child: Container(
margin: EdgeInsets.only(left: 15, right: 15),
height:100,
width: double.maxFinite,
decoration: BoxDecoration(
color: selected == 'Second' ? Colors.redAccent : Colors.lightBlueAccent,
),
child: ListTile(
title: Text(
'Second',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontFamily: 'WorksSansSemiBold',
fontWeight: FontWeight.bold,
),
),
),
),
),
Padding(padding: EdgeInsets.only(top: 20)),
GestureDetector(
onTap: () {
setState(() {
selected = "Third";
});
},
child: Container(
margin: EdgeInsets.only(left: 15, right: 15),
height:100,
width: double.maxFinite,
decoration: BoxDecoration(
color: selected == 'Third' ? Colors.redAccent : Colors.lightBlueAccent,
),
child: ListTile(
title: Text(
'Third',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontFamily: 'WorksSansSemiBold',
fontWeight: FontWeight.bold,
),
),
),
),
),
SizedBox(
height: 40,
),
MaterialButton(
child: Text("Submit"),
color: Colors.blueGrey,
textColor: Colors.white,
onPressed: () {},
),
],
),
),
);
}
}
I am taking the requirement as you don't want to toggle, but to select multiple items. This is the solution.
In Flutter, creating a different StatefulWidget for the buttons, will be unique for every button, and when you select the buttons. And hitting each button will have unique informations only. I know it is little confusing but follow this, and you will understand.
class MultipleSelectItems extends StatefulWidget {
#override
_MultipleSelectItemsState createState() => _MultipleSelectItemsState();
}
class _MultipleSelectItemsState extends State<MultipleSelectItems> {
// This is responsible to crate your buttons
// Every button is created will be having it's unique instance only
// Means, if you hit one button, it won't effect another, and you can select
// multiple
// And you don't have to declare your buttons multiple times in the code
// Which is indeed bad way of coding :)
List<Widget> get listTileWidgets{
List<Widget> _widget = [SizedBox(height: 40.0)];
List<String> _buttonName = ['First', 'Second', 'Third', 'Fourth'];
// ListTileWidget is defined below in another StatefulWidget
_buttonName.forEach((name){
_widget.add(ListTileWidget(name: name));
_widget.add(SizedBox(height: 20.0));
});
return _widget;
}
#override
Widget build(BuildContext context) {
return Material(
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: this.listTileWidgets
)
)
);
}
}
// This will accept name of the button which will be used to be given
// plus maintaining the uniqueness
class ListTileWidget extends StatefulWidget{
final String name;
ListTileWidget({Key key, this.name}):super(key:key);
#override
ListTileWidgetState createState() => ListTileWidgetState();
}
class ListTileWidgetState extends State<ListTileWidget>{
bool isTapped = false;
#override
Widget build(BuildContext context){
return GestureDetector(
onTap: () {
setState(() => isTapped = true);
},
child: Container(
margin: EdgeInsets.only(left: 15, right: 15),
height:100,
color: isTapped ? Colors.redAccent : Colors.lightBlueAccent,
width: double.maxFinite,
child: ListTile(
title: Text(
widget.name,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontFamily: 'WorksSansSemiBold',
fontWeight: FontWeight.bold,
)
)
)
)
);
}
}
Result you will get is below:
I am sorry that, I have not added your "Submit" button. So in order to make that thing visible in your code, simply add this in your Column only, and you will be good to go:
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
this.listTileWidgets,
SizedBox(height: 40),
MaterialButton(
child: Text("Submit"),
color: Colors.blueGrey,
textColor: Colors.white,
onPressed: () {},
)
]
)
That's pretty much it now.
I've got your answer. Changing the string variable to be an array can complete what you are looking to do. Then by checking if "First" or "Second" or "Third" is in the array we can determine what color the ListTile should be. Also when the ListTile is tapped we need to check if the array contains that string to determine if we are going to remove the string from the array (aka turning the color to blue) or if we need to add the string to the array (aka turning the color to red). Below I have included all of those changes to your class. Hope this answer helps! Comment if you have any questions
class MultipleSelectItems extends StatefulWidget {
#override
_MultipleSelectItemsState createState() => _MultipleSelectItemsState();
}
class _MultipleSelectItemsState extends State<MultipleSelectItems> {
var theSelected = ["First"];
#override
Widget build(BuildContext context) {
return Material(
child: Container(
child: GestureDetector(
child: Column(
children: <Widget>[
SizedBox(
height: 40,
),
GestureDetector(
onTap: () {
setState(() {
if(theSelected.contains("First")) {
theSelected.remove("First");
}
else {
theSelected.add("First");
}
});
},
child: Container(
margin: EdgeInsets.only(left: 15, right: 15),
height: 100,
width: double.maxFinite,
decoration: BoxDecoration(
color: theSelected.contains('First') ? Colors.redAccent : Colors.lightBlueAccent,
),
child: ListTile(
title: Text(
'First',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontFamily: 'WorksSansSemiBold',
fontWeight: FontWeight.bold,
),
),
),
),
),
Padding(padding: EdgeInsets.only(top: 20)),
GestureDetector(
onTap: () {
setState(() {
if(theSelected.contains("Second")) {
theSelected.remove("Second");
}
else {
theSelected.add("Second");
}
});
},
child: Container(
margin: EdgeInsets.only(left: 15, right: 15),
height:100,
width: double.maxFinite,
decoration: BoxDecoration(
color: theSelected.contains('Second') ? Colors.redAccent : Colors.lightBlueAccent,
),
child: ListTile(
title: Text(
'Second',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontFamily: 'WorksSansSemiBold',
fontWeight: FontWeight.bold,
),
),
),
),
),
Padding(padding: EdgeInsets.only(top: 20)),
GestureDetector(
onTap: () {
setState(() {
if(theSelected.contains("Third")) {
theSelected.remove("Third");
}
else {
theSelected.add("Third");
}
});
},
child: Container(
margin: EdgeInsets.only(left: 15, right: 15),
height:100,
width: double.maxFinite,
decoration: BoxDecoration(
color: theSelected.contains("Third") ? Colors.redAccent : Colors.lightBlueAccent,
),
child: ListTile(
title: Text(
'Third',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontFamily: 'WorksSansSemiBold',
fontWeight: FontWeight.bold,
),
),
),
),
),
SizedBox(
height: 40,
),
MaterialButton(
child: Text("Submit"),
color: Colors.blueGrey,
textColor: Colors.white,
onPressed: () {},
),
],
),
),
),
);
}
}

trying to add to bag and to update prices and cups

I am trying to do this test TODOs: but i have been have issuses pls help: i am trying to Uncomment the _confirmOrderModalBottomSheet() method to show summary of order, Uncomment the setState() function to clear the price and cups, and Change the 'price' to 0 when this button is clicked Increment the _cupsCounter when 'Add to Bag' button is clicked, and to Call setState((){}) method to update both price and cups counter when 'Add to Bag' button is clicked
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: 'Coffee Test',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.white,
),
home: MyHomePage(title: 'Coffee Test'),
);
}
}
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 _selectedPosition = -1;
String _coffeePrice ="0";
int _cupsCounter =0;
int price = 0;
String _currency ="₦";
static const String coffeeCup ="images/coffee_cup_size.png";
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
title: FlatButton(
onPressed: (){
//TODO: Uncomment the _confirmOrderModalBottomSheet() method to show summary of order
//_confirmOrderModalBottomSheet(totalPrice: "$_currency$price", numOfCups: "x $_cupsCounter");
},
child: Text("Buy Now",style: TextStyle(color: Colors.black87),),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(18.0), side: BorderSide(color: Colors.blue))
),
actions: [
InkWell(
onTap: () {
//TODO: Uncomment the setState() function to clear the price and cups
//TODO: Change the 'price' to 0 when this button is clicked
setState(() {
this.price = -1;
this._cupsCounter = 0;
});
Icon(Icons.clear);
}),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
height: double.maxFinite,
alignment: Alignment.center,
child: Text("$_cupsCounter Cups = $_currency$price.00", style: TextStyle(fontSize: 18),),
),
)
],
),
body: Padding(padding: EdgeInsets.all(20), child: _mainBody(),) // This trailing comma makes auto-formatting nicer for build methods.
);
}
Widget _mainBody(){
return SingleChildScrollView(
child: Container(
height: double.maxFinite,
width: double.maxFinite,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 0,
child: Stack(
children: [
Container(
width: double.maxFinite,
height: 250,
margin: EdgeInsets.only(left: 50, right: 50, bottom: 50, top: 60),
decoration: BoxDecoration(borderRadius:
BorderRadius.all(Radius.circular(180)),
color: Color.fromRGBO(239, 235, 233, 100)),
),
Container(
alignment: Alignment.center,
width: double.maxFinite,
height: 350,
child: Image.asset("images/cup_of_coffee.png", height: 300,),
)
],
)),
Padding(padding: EdgeInsets.all(10),),
Expanded(flex: 0,child: Text("Caffè Americano",
style: TextStyle(fontWeight: FontWeight.bold,
fontSize: 30),)),
Padding(padding: EdgeInsets.all(6),),
Expanded(flex: 0, child: Text("Select the cup size you want and we will deliver it to you in less than 48hours",
style: TextStyle(fontWeight: FontWeight.bold,
fontSize: 14, color: Colors.black45,),
textAlign: TextAlign.start,),
),
Container(
margin: EdgeInsets.only(top: 30, left: 20),
height: 55,
width: double.maxFinite,
alignment: Alignment.center,
child:Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
RichText(text: TextSpan(
text: _currency,
style: TextStyle(fontWeight: FontWeight.bold,
fontSize: 25, color: Colors.black87),
children: [
TextSpan(text: _coffeePrice, style: TextStyle(fontSize: 50, fontWeight: FontWeight.bold))
]
),),
Padding(
padding: EdgeInsets.only(right: 15),
),
ListView.builder(itemBuilder: (context, index){
return InkWell(
child: _coffeeSizeButton(_selectedPosition == index,
index ==0? "S" : index ==1? "M": "L"),
onTap: (){
setState(() {
this._coffeePrice= index ==0? "300" : index ==1? "600": "900";
_selectedPosition = index;
});
},
);
}, scrollDirection: Axis.horizontal,
itemCount: 3, shrinkWrap: true,),
],),
),
Container(
margin: EdgeInsets.only(top: 30),
padding: EdgeInsets.all(10),
width: double.maxFinite,
height: 70,
child: FlatButton(onPressed: (){
//TODO: Currently _cupsCounter only show 1 when this button is clicked.
// TODO: Increment the _cupsCounter when 'Add to Bag' button is clicked'
//TODO: Call setState((){}) method to update both price and cups counter when 'Add to Bag' button is clicked
this._cupsCounter = 1;
this.price += int.parse(_coffeePrice);
}, child: Center(child: Text("Add to Bag",
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white),)
,),
color: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50)
),
),
)
],
),
),
);
}
Widget _coffeeSizeButton(bool isSelected, String coffeeSize){
return Stack(
children: [
Container(alignment: Alignment.center, width: 55,
child: Text(coffeeSize, style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold,
color: isSelected? Colors.blue: Colors.black45),),),
new Container(
margin: EdgeInsets.only(right: 10),
child: Image.asset(coffeeCup, width:50, color: isSelected ? Colors.blue: Colors.black45,),
decoration: BoxDecoration(border: Border(top: BorderSide(color: isSelected? Colors.blue: Colors.black45,
width: isSelected? 2: 1), left: BorderSide(color: isSelected? Colors.blue: Colors.black45,
width: isSelected? 2: 1), bottom: BorderSide(color: isSelected? Colors.blue: Colors.black45,
width: isSelected? 2: 1), right: BorderSide(color: isSelected ?Colors.blue: Colors.black45 ,
width: isSelected? 2: 1)), borderRadius: BorderRadius.all(Radius.circular(5))),
)
],
);
}
void _confirmOrderModalBottomSheet({String totalPrice, String numOfCups}){
showModalBottomSheet(
context: context,
builder: (builder){
return new Container(
height: 150.0,
color: Colors.transparent, //could change this to Color(0xFF737373),
//so you don't have to change MaterialApp canvasColor
child: new Container(
padding: EdgeInsets.all(10),
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(10.0),
topRight: const Radius.circular(10.0))),
child: Column(
children: [
Container(
child: Text("Confirm Order",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),),
alignment: Alignment.center, height: 30, decoration: BoxDecoration(
), ),
_getEstimate(totalPrice, numOfCups)
],
)),
);
}
);
}
Widget _getEstimate(String totalPrice, String numOfCups){
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Image.asset("images/cup_of_coffee.png", height: 70, width: 50,),
Padding(padding: EdgeInsets.all(10)),
Text(numOfCups, style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),),
Padding(padding: EdgeInsets.all(10)),
Text(totalPrice, style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),)
],
);
}
}
You're setting 1 to your _cupsCounter instead of adding one to it.
When updating your values, putting the operation i.e _cupsCounter += 1; in setState will update the state of your widget which makes values change in your widgets.
setState((){
_cupsCounter += 1; // make it +=1 instead of =1.
price += int.parse(_coffeePrice);
});
Also you can use setState by putting it after your operation which will update the state of your widget after the operation is done.
_cupsCounter += 1; // make it +=1 instead of =1.
price += int.parse(_coffeePrice);
setState((){});
Full code should look like this.
Container(
margin: EdgeInsets.only(top: 30),
padding: EdgeInsets.all(10),
width: double.maxFinite,
height: 70,
child: FlatButton(onPressed: (){
// Currently _cupsCounter only show 1 when this button is clicked.
// Increment the _cupsCounter when 'Add to Bag' button is clicked'
// Call setState((){}) method to update both price and cups counter when 'Add to Bag' button is clicked
setState((){
_cupsCounter += 1; // make it +=1 instead of =1.
price += int.parse(_coffeePrice);
}); // call setState like this
}, child: Center(child: Text("Add to Bag",
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white),)
,),
color: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50)
),
),
)

adding ListView.builder

I'm trying to make the displayAccoutList() scrollable.
I've tried to use ListView but it didn't work. I'm thinking to use ListView.builder but I don't know how to create data for accountItems()
enter code here`import 'package:flutter/material.dart';
import 'app_drawer.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Accounts',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Account(),
);
}
}
class Account extends StatefulWidget {
#override
_AccountState createState() => _AccountState();
}
class _AccountState extends State<Account> {
Card topArea() =>
Card(
margin: EdgeInsets.all(10.0),
elevation: 1.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(50.0))),
child: Container(
decoration: BoxDecoration(
gradient: RadialGradient(
colors: [Color(0xFFFF5722), Color(0xFFFF5722)])),
padding: EdgeInsets.all(5.0),
// color: Color(0xFF015FFF),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
onPressed: () {},
),
Text("Savings",
style: TextStyle(color: Colors.white, fontSize: 20.0)),
IconButton(
icon: Icon(
Icons.arrow_forward,
color: Colors.white,
),
onPressed: () {},
)
],
),
Center(
child: Padding(
padding: EdgeInsets.all(5.0),
child: Text(r"£ " "100,943.33",
style: TextStyle(color: Colors.white, fontSize: 24.0)),
),
),
SizedBox(height: 35.0),
],
)),
);
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: AppDrawer(),
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.grey, //change your color here
),
backgroundColor: Colors.white,
elevation: 0.0,
title: Text(
"Accounts",
style: TextStyle(color: Colors.black),
),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(
Icons.search,
color: Colors.grey,
),
onPressed: () {},
)
],
),
body: Container(
color: Colors.white,
child: Column(
children: <Widget>[
topArea(),
SizedBox(
height: 40.0,
child: Icon(Icons.refresh,
size: 35.0,
color: Color(0xFFFF5722),
),
),
displayAccoutList()
],
),
),
bottomNavigationBar: BottomAppBar(
elevation: 0.0,
child: Container(
margin: EdgeInsets.symmetric(vertical: 20.0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
FlatButton(
padding:
EdgeInsets.symmetric(vertical: 12.0, horizontal: 30.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0)),
color: Color(0xFFFF5722),
// borderSide: BorderSide(color: Color(0xFF015FFF), width: 1.0),
onPressed: () {},
child: Text("ACTIVITY"),
),
OutlineButton(
padding:
EdgeInsets.symmetric(vertical: 12.0, horizontal: 28.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0)),
borderSide: BorderSide(color: Color(0xFFFF5722), width: 1.0),
onPressed: () {},
child: Text("STATEMENTS"),
),
OutlineButton(
padding:
EdgeInsets.symmetric(vertical: 12.0, horizontal: 28.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0)),
borderSide: BorderSide(color: Color(0xFFFF5722), width: 1.0),
onPressed: () {},
child: Text("DETAILS"),
)
],
),
),
)
);
}
}
Container accountItems(String item, String charge, String dateString,
String type,
{Color oddColour = Colors.white}) =>
Container(
decoration: BoxDecoration(color: oddColour),
padding:
EdgeInsets.only(top: 20.0, bottom: 20.0, left: 5.0, right: 5.0),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(item, style: TextStyle(fontSize: 16.0)),
Text(charge, style: TextStyle(fontSize: 16.0))
],
),
SizedBox(
height: 10.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(dateString,
style: TextStyle(color: Colors.grey, fontSize: 14.0)),
Text(type, style: TextStyle(color: Colors.grey, fontSize: 14.0))
],
),
],
),
);
displayAccoutList() {
return Container(
margin: EdgeInsets.all(15.0),
child: Column(
children: <Widget>[
accountItems("M KING", r"+ £ 4,946.00", "15-07-19", "Credit",
oddColour: const Color(0xFFF7F7F9)),
accountItems(
"Gordon Street Tenants", r"+ £ 5,428.00", "15-07-19", "Credit"),
accountItems("Amazon EU", r"+ £ 746.00", "15-07-19", "Credit",
oddColour: const Color(0xFFF7F7F9)),
accountItems(
"Floww LTD", r"+ £ 5,526.00", "15-07-19", "Credit"),
accountItems(
"KLM", r"- £ 2,500.00", "10-07-19", "Payment",
oddColour: const Color(0xFFF7F7F9)),
],
),
);
`
The other page app_drawer.dart
`
import 'package:flutter/material.dart';
class AppDrawer extends StatefulWidget {
#override
_AppDrawerState createState() => _AppDrawerState();
}
class _AppDrawerState extends State<AppDrawer> {
#override
Widget build(BuildContext context) {
return SizedBox(
width: 160.0,
child: Drawer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 50.0),
child: FlatButton.icon(
icon: Icon(
Icons.arrow_back,
color: Colors.grey,
),
onPressed: null,
label: Text("Back",
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 16.0,
color: Colors.black)),
color: Colors.black,
),
),
buildMenuItem(Icons.account_balance, "ACCOUNTS",
opacity: 1.0, color: Color(0xFFFF6E40)),
Divider(),
buildMenuItem(Icons.compare_arrows, "TRANSFER"),
Divider(),
buildMenuItem(Icons.receipt, "STATEMENTS"),
Divider(),
buildMenuItem(Icons.attach_money, "PAYMENTS"),
Divider(),
buildMenuItem(Icons.sentiment_satisfied, "INVESTMENTS"),
Divider(),
buildMenuItem(Icons.phone, "SUPPORT"),
Divider()
],
),
),
);
}
Opacity buildMenuItem(IconData icon, String title,
{double opacity = 0.3, Color color = Colors.black}) {
return Opacity(
opacity: opacity,
child: Center(
child: Column(
children: <Widget>[
SizedBox(
height: 20.0,
),
Icon(
icon,
size: 50.0,
color: color,
),
SizedBox(
height: 10.0,
),
Text(title,
style: TextStyle(
fontWeight: FontWeight.w500, fontSize: 14.0, color: color)),
SizedBox(
height: 10.0,
),
],
),
),
);
}
}
`
To able to scroll through the section and have unlimited amount of transaction
I think this is what you are going for.
In this snippet, I defined Language as a class with attributes language and rating.
Then I created a list of languages in the stateless widget TheList.
Finally, I used the listView.builder to map the list for its length and display text that shows the attributes of the languages.
Let me know if you have any questions!
import 'package:flutter/material.dart';
class Language {
const Language({this.language,this.rating});
final String language;
final String rating;
}
class TheList extends StatelessWidget {
// Builder methods rely on a set of data, such as a list.
final List<Language> _languages = [
const Language(language: "flutter", rating: "amazing"),
const Language(language: "javascript", rating: "stellar"),
const Language(language: "java", rating: "sucks"),
];
// First, make your build method like normal.
// Instead of returning Widgets, return a method that returns widgets.
// Don't forget to pass in the context!
#override
Widget build(BuildContext context) {
return _buildList(context);
}
// A builder method almost always returns a ListView.
// A ListView is a widget similar to Column or Row.
// It knows whether it needs to be scrollable or not.
// It has a constructor called builder, which it knows will
// work with a List.
ListView _buildList(context) {
return ListView.builder(
// Must have an item count equal to the number of items!
itemCount: _languages.length,
// A callback that will return a widget.
itemBuilder: (context, index) {
// In our case, a Language and its rating for each language in the list.
return Text(_languages[index].language + ": " + _languages[index].rating);
},
);
}
}