Screen not updating in a statefulWidget in Flutter - flutter

I have a statefulWidget in Flutter like this:
class GameScreen extends StatefulWidget {
#override
GameScreenState createState() => GameScreenState();
}
class GameScreenState extends State<GameScreen> {
List<String> selectedWord = ['h', 'e', 'l', 'l', 'o'];
Widget _letterInput() {
return Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
for (var letter in selectedWord) LetterInput(letter: letter)
],
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
_letterInput(),
],
)),
);
}
}
class LetterInput extends StatelessWidget {
LetterInput({this.letter});
final String letter;
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
decoration: BoxDecoration(
border: BorderDirectional(
bottom: BorderSide(width: 6.0, color: Colors.green))),
child: Text(letter,
textAlign: TextAlign.center,
style:
GoogleFonts.acme(fontSize: 28.0, fontWeight: FontWeight.w400)));
}
}
The problem is that when I first launch the app with this widget, I can see hello on the screen, but if I go on and change hello to hellos in selectedWord, that does not update the screen and it still shows me hello even though the hot reload is turned on. I have to go and restart the app so it shows me hellos. How could I fix this?

In my experience, hot reload keeps states. Try hot restart instead?
Referring to your comment, if you want to keep using hot reload, I suggest you pull out the variable to your widget itself (if that is an option for you), like this:
class GameScreen extends StatefulWidget {
final List<String> selectedWord = ['h', 'e', 'l', 'l', 'o'];
#override
GameScreenState createState() => GameScreenState();
}
class GameScreenState extends State<GameScreen> {
Widget _letterInput() {
return Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
for (var letter in widget.selectedWord) LetterInput(letter: letter)
],
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
_letterInput(),
],
)),
);
}
}

Related

Flutter : I want to change an image when you tap the image, and others are not affected by the tap

I am creating a simple app in Flutter. There are 7 images on 1 screen. I need a function that you can change an image when you tap one of the images. However, now when I tap an image, the other 6 images are also changed. I made a variable "isReal" to put into buildButton() and "isReal" would be switched true and false in the For statement which switch "isReal" in buildButton(). But, that did not work. Could you give me some advice on this problem? Thank you.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';
class Screen extends StatefulWidget {
#override
_ScreenState createState() => _ScreenState();
}
class _ScreenState extends State<Screen> {
bool isReal = true;
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.teal[100],
// appBar: AppBar(
// title: Text('AnimalSounds'), backgroundColor: Colors.teal),
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('cat.mp3', Colors.red, 'images/cat.png',
'images/cat_real.jpg'),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('dog.mp3', Colors.yellow, 'images/dog.png',
'images/cow.png'),
buildButton('cow.mp3', Colors.orange, 'images/cow.png',
'images/dog.png'),
])),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('pig.mp3', Colors.green, 'images/pig.png',
'images/elephant.png'),
buildButton('elephant.mp3', Colors.teal,
'images/elephant.png', 'images/rooster.png'),
buildButton('rooster.mp3', Colors.blue,
'images/rooster.png', 'images/pig.png'),
])),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('goat.mp3', Colors.purple, 'images/goat.jpg',
'images/pig.png'),
],
)),
],
),
)));
}
Expanded buildButton(sound, color, simpleImage, realImage) {
return Expanded(
child: FlatButton(
onPressed: () {
setState(() {
isReal = !isReal;
});
final player = AudioCache();
player.play(sound);
},
color: color,
child: isReal ? Image.asset(simpleImage) : Image.asset(realImage),
));
}
}
Ok, you have variable isReal that is the same for entire class (i.e. each button use the same variable). So when you change it's value by tapping on one button it affects all other buttons as well.
To solve this issue I would recommend to move button implementation into a separate Statefull widget. This way you can keep your Screen class as Stateless.
UPD:
Obviously you should watch some tutorials on how to make this on your own. But just for this time this is how it should look like after you separate widgets.
What I did here is:
Create new widget class FlipButton
Move code from your method into build function of new widget
Add parameters to constructor
This way when each FlipButton will have it's own isReal variable.
NOTE: I didn't try to compile it so there might be some errors.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';
class Screen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.teal[100],
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
//replace all occurances on `buildButton` method with new widget
FlipButton(sound: 'cat.mp3', color: Colors.red, simpleImage: 'images/cat.png', realImage: 'images/cat_real.jpg'),
Expanded(
child: Row(crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[
FlipButton(sound: 'dog.mp3', color: Colors.yellow, simpleImage: 'images/dog.png', realImage: 'images/cow.png'),
FlipButton(sound: 'cow.mp3', color: Colors.orange, simpleImage: 'images/cow.png', realImage: 'images/dog.png'),
])),
Expanded(
child: Row(crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[
FlipButton(sound: 'pig.mp3', color: Colors.green, simpleImage: 'images/pig.png', realImage: 'images/elephant.png'),
FlipButton(sound: 'elephant.mp3', color: Colors.teal, simpleImage: 'images/elephant.png', realImage: 'images/rooster.png'),
FlipButton(sound: 'rooster.mp3', color: Colors.blue, simpleImage: 'images/rooster.png', realImage: 'images/pig.png'),
])),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
FlipButton(sound: 'goat.mp3', color: Colors.purple, simpleImage: 'images/goat.jpg', realImage: 'images/pig.png'),
],
)),
],
),
),
),
);
}
}
/// You can copy this widget into separate file for better formatting
///
class FlipButton extends StatefulWidget {
//declare final variables
final String sound;
final Color color;
final String simpleImage;
final String realImage;
//constructor for this class
const FlipButton({
Key? key,
required this.sound,
required this.color,
required this.simpleImage,
required this.realImage,
}) : super(key: key);
#override
_FlipButtonState createState() => _FlipButtonState();
}
class _FlipButtonState extends State<FlipButton> {
//inside the state declare variable that is about to change
bool isReal = false;
#override
Widget build(BuildContext context) {
return Expanded(
child: FlatButton(
onPressed: () {
setState(() {
isReal = !isReal;
});
final player = AudioCache();
player.play(sound);
},
color: widget.color,
child: isReal ? Image.asset(widget.simpleImage) : Image.asset(widget.realImage),
));
}
}
You can use Random class from dart:math to generate the next random image.
Exemple :
int imageNumber = 1;
void updateImage() {
setState(() {
//Random.nextInt(n) returns random integer from 0 to n-1
imageNumber = Random().nextInt(7) + 1;
});
}
#override
Widget build(BuildContext context) {
return Center(
child: Expanded(
child: Padding(
padding: const EdgeInsets.all(50.0),
child: FlatButton(
child: Image.asset('images/dice$imageNumber.png'),
onPressed: () {
updateImage();
},
),
),
),
);
}

How to change the colour of button on press to green and other buttons in row back to neutral

The idea behind this is i would like users to select their sex, sexual orientation and relationship status. So there would be a button in the first row saying "Male" another one saying "female" and another one saying "other". Below that there would be 3 other buttons saying "straight" "gay/lesbian" and "other" and below that another row with 3 buttons (options). Once the user clicks a button the button toggles on essentially and it goes from e.g black to green. I created the boolean toggleOn and will be setting to true or false on button press. The issue is right now i am getting an error on the screen and i think it is because i am going over the available pixels and singleChildScrollView does not work. Any ideas?
Also i am sorry if you are cringing right now i am just making a personal project to learn to code.
This is the screen where i would like to have 3 rows with 3 buttons each
import 'package:./components/rounded_button.dart';
import 'package:./screens/register_screen.dart';
import 'package:flutter/material.dart';
class UserRegisterPreferences extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Scaffold(
backgroundColor: Color(0xff1e1e1e),
body: Body(),
),
);
}
}
class Body extends StatefulWidget {
#override
_BodyState createState() => _BodyState();
}
class _BodyState extends State<Body> {
#override
Widget build(BuildContext context) {
bool toggleOn = false;
Size size = MediaQuery.of(context).size;
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
verticalDirection: VerticalDirection.down,
children: <Widget>[
Container(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
roundedButton(
press: () => setState(() => toggleOn = !toggleOn),
),
roundedButton(
press: () => setState(() => toggleOn = !toggleOn),
),
roundedButton(),
],
),
),
),
Column(
children: <Widget>[
roundedButton(),
roundedButton(),
roundedButton(),
],
),
Column(children: <Widget>[
roundedButton(),
roundedButton(),
roundedButton(),
]),
],
);
}
}
This is the file that contains the button so i can keep reusing on the app
import 'package:./constants.dart';
import 'package:flutter/material.dart';
// ignore: camel_case_types
class roundedButton extends StatelessWidget {
final String text;
final Function press;
final Color color, textColor;
const roundedButton({
Key key,
this.text,
this.press,
this.color = kPrimaryColor,
this.textColor = Colors.white,
}) : super(key: key);
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Container(
margin: EdgeInsets.symmetric(vertical: 10),
width: size.width * 0.7,
child: ClipRRect(
borderRadius: BorderRadius.circular(29),
child: TextButton(
style: TextButton.styleFrom(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 40),
primary: Colors.white,
backgroundColor: kPrimaryColor,
),
onPressed: press,
child: Text(text),
),
),
);
}
}

Why does my text suddenly get whitespace when applying a style?

Here is my flutter code:
class LandingScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
LandingPageForm(),
],
),
);
}
}
class LandingPageForm extends StatefulWidget {
#override
LandingPageFormState createState() {
return LandingPageFormState();
}
}
final headerStyle = TextStyle();
class LandingPageFormState extends State<LandingPageForm> {
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Container(
color: Colors.grey,
padding: EdgeInsets.all(10),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
color: Colors.amber,
child: FittedBox(
child: Text(
'Hey there!',
style: headerStyle,
),
fit: BoxFit.fitWidth,
),
),
],
),
));
}
}
If I remove the headerStyle from the fitted textbox, the padding above disappears which is how I want it. As soon as I add a style though this whitespace appears and I have no idea what is causing it.
What is going on?
Closing this - it seems there is a persistent caching issue with styles on my device. Closing and reopening the app fixed the issue.

Listviewbuilder implementation inside Column won't work

I want to have a scrollable list on my home screen. I tried to implement my Listviewbuilder called Cardslist() into the home screen, but I always get this exception thrown: RenderFlex children have non-zero flex, incoming height constraints are unbounded. Heres the code for the home screen:
import 'package:biminda_app/Components/cards_list.dart';
import 'package:biminda_app/Components/real_new_finished_card.dart';
import 'package:flutter/material.dart';
import 'package:biminda_app/Components/custom_Buttons.dart';
import 'package:biminda_app/Components/constants.dart';
import 'package:flutter/rendering.dart';
import 'package:biminda_app/Screens/new_card_screen1.dart';
import 'package:biminda_app/Screens/settings.dart';
import 'package:biminda_app/Components/card_data.dart';
import 'package:biminda_app/Components/cards_list.dart';
class HomeScreen extends StatefulWidget {
static const String id = 'home_screen';
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
String individualsName;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(
20,
40,
20,
0,
),
child: TextField(
style: TextStyle(
color: Colors.black,
),
decoration: kTextFieldInputDecoration,
onChanged: (value) {
individualsName = value;
// TODO: Der Input muss das Individum in der Liste
// TODO: erkennen und anzeigen
},
),
),
//TODO HIER
Expanded(
child: Column(
children: <Widget>[
CardsList(),
],
)),
Center(
child: Container(
child: MainButton(
functionality: 'New',
onPressed: () {
Navigator.pushNamed(context, NewCard.id);
}),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SideButton(
functionality: 'Settings',
onPressed: () {
Navigator.pushNamed(context, Settings.id);
}),
SideButton(
functionality: 'Calendar',
onPressed: () {
Navigator.pushNamed(context, Settings.id);
}),
],
),
),
],
),
);
}
}
And here's the code for Cardslist():
class CardsList extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Consumer<CardData>(builder: (context, cardData, child) {
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (context, index) {
final card = cardData.cards[index];
return FinalCardCreation(
finalname: card.cname,
finalbirthday: card.cbirthday,
);
});
});
}
}
The code for the created card FinalCardCreation():
class CardFinish extends StatefulWidget {
#override
CardFinishState createState() => CardFinishState();
}
class CardFinishState extends State<CardFinish> {
#override
Widget build(BuildContext context) {
return SizedBox(
height:
MediaQuery.of(context).size.height * 0.5, //<-- set height of the card
child: FinalCardCreation(),
);
}
}
class FinalCardCreation extends StatelessWidget {
String finalname;
String finalbirthday;
FinalCardCreation({
Key key,
#required this.finalname,
#required this.finalbirthday,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Card(
color: Color(0xFFef9a9a),
margin: EdgeInsets.all(2),
elevation: 8,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(22)),
child: Column(
children: <Widget>[
SizedBox(height: 8),
Expanded(
child: FinalCardContent(
name: finalname,
birthday: finalbirthday,
),
)
],
),
);
}
}
class FinalCardContent extends StatelessWidget {
String name;
String birthday;
FinalCardContent({Key key, #required this.name, #required this.birthday})
: super(key: key);
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'$name',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 50.0,
color: Colors.black,
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'$birthday',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 50.0,
color: Colors.black,
),
),
),
],
),
);
}
}
I tried to wrap my Cardslist() multiple ways but I always got this exception. Thank you for your time and answer.
Column is a widget that can grow infinitely in height. It does not impose any height constraints to its children. Expanded are a smart way to include ListViews in Column since they fit all the possible space of the Column on screen, but impose a constraint to their children.
You can either remove the Column wrapping your CardList or, if you really need that Column for other stuff later, try wrapping CardList in another Expanded.

how to adjust the container as per the device screen in flutter

my app look like below
once logged in, in home page it has 3 tabs, and also a bottom navigation bar, and a app bar.
below the tab bar there is a container it contain many cards. I have given a fixed height to container, but when I checked in multiple devices there is a issue , i.e for the container having cards, getting overflow.
I tried to take the entire screen height then took the 70% for the container , but in phones with smaller resolution its showing overflow, if I adjusted as per that screen , In bigger screen , container takes very less space and more than 20% of space is wasted.
I am adding my code below,
here is my dashboard.dart code: ===>
import './generate_report_list.dart';
import './provider_classes.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:bmnav/bmnav.dart' as bmnav;
import './dashboard_view.dart';
class DashBoard extends StatefulWidget {
#override
_DashBoardState createState() => _DashBoardState();
}
class _DashBoardState extends State<DashBoard> with WidgetsBindingObserver {
int _currentIndex = 0;
Widget _view;
double maxHeight;
double maxWidth;
double maxCardWidth;
List<String> headers = ['Dashboard', 'Reports List', 'Profile', 'Settings'];
List<IconData> icons = [
Icons.dashboard,
Icons.insert_chart,
Icons.account_circle,
Icons.settings,
];
List<String> images = [
('assets/dashboard.png'),
('assets/growth.png'),
('assets/user.png'),
('assets/settings.png'),
];
getView(int index) {
List<Widget> _viewList = <Widget>[
GenerateReportList(),
GenerateReportList(),
GenerateReportList(),
GenerateReportList(),
];
setState(() {
_view = _viewList[index];
_currentIndex = index;
Provider.of<ScreenHeader>(context)
.setScreenHeader(headers[_currentIndex]);
});
}
#override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
#override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
#override
Widget build(BuildContext context) {
String appBarHeader = Provider.of<ScreenHeader>(context).getScreenHeader();
maxWidth = MediaQuery.of(context).size.width;
maxCardWidth = maxWidth / 2;
return Scaffold(
appBar: AppBar(
title: Text(
(appBarHeader ?? 'Dashboard'),
),
centerTitle: true,
),
body: _view ?? DashBoardView(),
bottomNavigationBar: bmnav.BottomNav(
onTap: (index) {
getView(index);
},
labelStyle: bmnav.LabelStyle(visible: true),
iconStyle:
bmnav.IconStyle(color: Colors.black, onSelectColor: Colors.red),
elevation: 10,
items: [
bmnav.BottomNavItem(Icons.home, label: 'Dashboard'),
bmnav.BottomNavItem(Icons.trending_up, label: 'Reports'),
bmnav.BottomNavItem(Icons.person, label: 'Profile'),
bmnav.BottomNavItem(Icons.settings, label: 'Settings')
],
),
);
}
}
generate_report_list.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:developer' as developer;
class GenerateReportList extends StatefulWidget {
#override
_GenerateReportListState createState() => _GenerateReportListState();
}
class _GenerateReportListState extends State<GenerateReportList>
with SingleTickerProviderStateMixin {
Future reportList;
List<String> typesOfReports = [];
String currentReportSummaryType;
TabController _tabController;
#override
void initState() {
super.initState();
currentReportSummaryType = 'detailed';
_tabController = TabController(vsync: this, length: 3);
}
void _handleTabSelection(var index) {
developer
.log("index: array:" + typesOfReports[0] + "," + typesOfReports[1]);
setState(() {
print("index is " + index);
if (index == 0) {
currentReportSummaryType = "Group A";
} else if (index == 1) {
currentReportSummaryType = "Group B";
} else if (index == 2) {
currentReportSummaryType = "Group C";
}
});
}
getBody() {
double maxHeight = MediaQuery.of(context).size.height;
developer.log('Max height:' + maxHeight.toString());
return Scaffold(
resizeToAvoidBottomInset: false,
body: Column(
children: [
Container(
child: TabBar(
labelColor: Colors.black,
tabs: <Widget>[
new Tab(text: 'Group A', icon: new Icon(Icons.list)),
new Tab(text: 'Group B', icon: new Icon(Icons.pie_chart)),
new Tab(text: 'Group C', icon: new Icon(Icons.insert_chart)),
],
controller: _tabController,
onTap: _handleTabSelection,
),
),
SingleChildScrollView(
child: Container(
margin: new EdgeInsets.all(0.0),
height: (maxHeight * 0.60),
child: SingleChildScrollView(
child:new Center(
child: Column(
children: <Widget>[
cardGen(),
cardGen(),
cardGen(),
cardGen(),
cardGen(),
cardGen(),
],
)))))
],
));
}
cardGen() {
return Card(
child: Container(
height: (MediaQuery.of(context).size.height * 0.6) * 0.25,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text("sample"),
Text("dummy"),
],
),
],
),
),
);
}
createCard(BuildContext context) {
double maxHeight = MediaQuery.of(context).size.height;
Container(
height: (maxHeight * 0.6) * 0.25,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text("sample"),
Text("dummy"),
],
),
],
),
);
}
#override
Widget build(BuildContext context) {
return getBody();
}
}
provider_classes.dart
import 'package:flutter/material.dart';
class ScreenHeader with ChangeNotifier {
String _screenHeader;
getScreenHeader() => _screenHeader;
setScreenHeader(String newHeader) {
_screenHeader = newHeader;
notifyListeners();
}
}
provider classes is just for displaying the data in appbar.
In dashboard.dart I am creating a appbar,and bottomsheet, and in generate_report_list I am adding 3 new tabs , for each tab once clicked I am displaying the cards.
How to assign the height to container carrying card so that it should fit on every device.,and how can I add scrollable to the tabs , i.e group A, group B, Group C.
Thanks
Change:
Column(
children: <Widget>[
cardGen(),
...
To:
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
cardGen(),
...