I am having difficulty figuring how to get a Row, which contains wrapped text, to appear centered in a Column.
The issue seems to be that Flexible (or Expanded for that matter) causes the Text widget to consume the entire remaining horizontal space in the Row. This seems fine for text layout purposes, i.e., determining the needed height for the text. However, it also seems to me that is should be possible that once the text has been laid out, the bounds of its widget can be "shrunk" to require only the minimum width necessary. (Notice the difference of width/space within the red bounding box in the images below.)
Is it possible to achieve this in Flutter? What am I overlooking?
I have searched high and low on SO and haven't found this specific question.
The closest related might be this but it's difficult to be certain the way that question was asked. (And it did not receive any answers.)
What I am seeing
What I would like to see
What I have tried
Several permutations of Flexible and Expanded, around the Text, Row, and Column in various combinations
Several different values for fit and flex (with Flexible)
IntrinsicWidth parent on Column
softWrap
Code
(Based on the "Counter" sample from DartPad.)
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({
Key? key,
required this.title,
}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.blueAccent),
),
width: 300,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'\u{1F603}',
style: TextStyle(
fontSize: 24.0,
),
),
Flexible(
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.red),
),
child: const Text(
'Some text that ends up taking_two_lines',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
),
),
],
),
],
),
),
);
}
}
Welp, as I was typing up this question, I discovered the solution, so I may as well write it up for others.
The trick was to use the textWidthBasis argument of Text and set it to TextWidthBasis.longestLine.
If you has parent widget set yours to center too
In my case i set My Colum(mainAlignment to center and it is work for me)
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.blueAccent),
),
alignment: Alignment.center,
width: 300,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'\u{1F603}',
style: TextStyle(
fontSize: 24.0,
),
),
Flexible(
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.red),
),
child: const Text(
'Some text that ends up taking_two_lines',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
),
),
],
),
],
),
),
Try below code hope its help to you I have try same as your expected design
Your Widget:
Scaffold(
appBar: AppBar(
actions: [
const Center(
child: Padding(
padding: EdgeInsets.all(8),
child: Text(
'Flutter',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
),
),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SizedBox(
width: 50,
),
const Text(
'\u{1F603}',
style: TextStyle(
fontSize: 24.0,
),
),
Expanded(
child: const Text(
'Some text that ends up taking_two_lines',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
),
],
),
],
),
),
Result Screen->
Related
For some reason everything fits perfectly fine on my device but once using it on a smaller device with screen size 5.5" the screen is scrolling and some of the elements or widgets are outside the screen as shown in the images below. I have listed my code below as well.
How can I prevent this from happening and fit everything inside the screen, regardless the size of the screen?
class OtpVerificationScreen extends StatefulWidget {
const OtpVerificationScreen({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() => _OtpVerificationScreen();
}
class _OtpVerificationScreen extends State<OtpVerificationScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.white,
body: SafeArea(
child: Center(
child: Column(
children: [
//Logo
const LogoForAuthScreens(),
const Text(
'Enter verification code',
style: TextStyle(
// fontWeight: FontWeight.bold,
fontSize: 26,
),
),
Container(
margin: const EdgeInsets.only(top: 30, bottom: 20),
child: const Text(
'We send a code to the following number:\n+01723456789',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black45,
),
),
),
Form(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
OtpInputField(),
OtpInputField(),
OtpInputField(),
OtpInputField(),
OtpInputField(),
OtpInputField(),
],
),
),
TextButton(
onPressed: () {},
child: const Text('Resend OTP'),
),
Container(
margin: const EdgeInsets.only(left: 30, top: 30, right: 30),
child: MaterialButton(
onPressed: () {
Navigator.of(context).pushNamed('/signup');
},
color: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
padding:
const EdgeInsets.symmetric(vertical: 20, horizontal: 30),
minWidth: double.infinity,
child: const Text(
'Continue',
style: TextStyle(
color: Colors.white,
),
),
),
),
],
),
),
),
);
}
}
You can wrap each widget inside your column widget with a Flexible widget. This will cause them to resize dynamically based on the available space.
I have a simple screen built using the code shown below. I want to keep the ad banner at the top at all times while the Container() below it to be scrollable. This is the reason I put SingleChildScrollView() in the lower container.
But it still overflows the screen with the following error:
════════ Exception caught by rendering library ═════════════════════════════════════════════════════
The following assertion was thrown during layout:
A RenderFlex overflowed by 162 pixels on the bottom.
This is what the screen looks like:
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
// colorFilter: ColorFilter.mode(Colors.white, BlendMode.color),
image: AssetImage("assets/feathers_bg.jpg"),
fit: BoxFit.cover,
),
),
child: Column(
children: [
AdmobBanner(
//below is test id
adUnitId: 'ca-app-pub-3940256099942544/6300978111',
adSize: AdmobBannerSize.FULL_BANNER,
),
Padding(
padding: const EdgeInsets.all(40.0),
child: SingleChildScrollView(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
padding: EdgeInsets.all(10),
child: Column(
children: [
Image.network(_birdDetails.thumbnail.source),
SizedBox(height: 10,),
Container(
child: Column(
children: [
Text(
_birdName,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
color: Colors.teal,
fontWeight: FontWeight.bold,
),
),
Text(
_birdDetails.description,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
fontStyle: FontStyle.italic,
),
),
],
),
),
SizedBox(height: 20,),
Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Text(
_birdDetails.extract,
textAlign: TextAlign.justify,
style: TextStyle(
fontSize: 16
),
),
),
SizedBox(height: 10,),
],
),
),
),
),
],
),
),
TL;DR version. Your SingleChildScrollView needs to be Expanded (you can put Expanded -> Padding - > SingleChildScrollView).
Longer version you can read in the official documentation, this section describes a similar scenario:
One common reason for this to happen is that the Column has been
placed in another Column (without using Expanded or Flexible around
the inner nested Column). When a Column lays out its non-flex children
(those that have neither Expanded or Flexible around them), it gives
them unbounded constraints so that they can determine their own
dimensions (passing unbounded constraints usually signals to the child
that it should shrink-wrap its contents). The solution in this case is
typically to just wrap the inner column in an Expanded to indicate
that it should take the remaining space of the outer column, rather
than being allowed to take any amount of room it desires.
And here is a bit simplified version of your code that is easily reproducible (to paste and run for example in dartpad):
import 'package:flutter/material.dart';
import 'dart:math';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'SO Question : 64200763'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
StringBuffer birdDetails;
var rng = new Random();
#override
initState(){
super.initState();
birdDetails = new StringBuffer();
for(int i=0; i<4000; i++){
birdDetails.write(String.fromCharCode(rng.nextInt(25) + 97));
if(rng.nextBool() && rng.nextBool()) birdDetails.write(' ');
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
decoration: BoxDecoration(
color: Colors.green[400],
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Column(
children: [
Container(
height: 100,
width: double.maxFinite,
color: Colors.yellow,
child: Text('Ad placeholder', textAlign: TextAlign.center)
),
Expanded(
child: Padding( // Here is your fix, place expanded above the SingleChildScrollView
padding: const EdgeInsets.all(40.0),
child: SingleChildScrollView(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
padding: EdgeInsets.all(10),
child: Column(
children: [
Image.network('https://picsum.photos/id/1024/512/288'),
SizedBox(height: 10,),
Container(
child: Column(
children: [
Text(
'Bird name',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
color: Colors.teal,
fontWeight: FontWeight.bold,
),
),
Text(
'Bird (random) description',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
fontStyle: FontStyle.italic,
),
),
],
),
),
SizedBox(height: 20,),
Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Text(
birdDetails.toString(),
textAlign: TextAlign.justify,
style: TextStyle(
fontSize: 16
),
),
),
SizedBox(height: 10,),
],
),
),
),
),
),
],
),
),
);
}
}
End result (as per how you organized the widgets, but without overflows):
PS, before posting a question I highly recommend stripping / replacing the code of all dependencies that some users might or might not have at hand (like AdMob), unnecessary assets (like AssetImage) and lastly class structures that aren't defined in the question (like birdDetails.thumbnail.source). It might help you debug the problem on your own and if it doesn't it makes it easier for people that are trying to help you ;).
Container(
child: Column(
children: <Widget>[
Container(
alignment: Alignment.topLeft,
padding: EdgeInsets.only(left: 10.0),
child: Text("Random Text",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black)),
),
Container(
alignment: Alignment.topLeft,
padding: EdgeInsets.all(10.0),
child: Text("Owner",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey)),
),
],
),
),
I don't know if it's an easy way. But for a simple reusable widget, you can place your widget inside a StatelessWidget or a StatefulWidget.
Here's the example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: <Widget>[
MyReusableWidget('Nikola Tesla', 'Owner'), //Input the name and role variable when you call the widget
MyReusableWidget('Albert Einstein', 'Developer'),
MyReusableWidget('Isaac Newton', 'Technician'),
],
),
),
);
}
}
class MyReusableWidget extends StatelessWidget {
final String name; // provide a place for the input's data
final String role;
MyReusableWidget(this.name, this.role);
#override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
Container(
alignment: Alignment.topLeft,
padding: EdgeInsets.only(left: 10.0),
child: Text(
name, // This is where you place your 'name' data
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.black),
),
),
Container(
alignment: Alignment.topLeft,
padding: EdgeInsets.all(10.0),
child: Text(
role, // This is where you place your 'role' data
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.grey),
),
),
],
),
);
}
}
I'm creating a widget called MyReusableWidget. I am gonna call that widget inside my MyApp 3 times. And then each widget should provide different names and roles.
So inside my MyReusableWidget, I provide two String data-types called name and role to store my data when I call the widget.
final String name; // provide a place for the input's data
final String role;
MyReusableWidget(this.name, this.role);
And then I want to place my name and role variable inside a Text widget:
child: Text(
name, // This is where you place your 'name' data
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.black),
),
and:
child: Text(
role, // This is where you place your 'role' data
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.grey),
),
After that, inside my MyApp widget, I can call MyReusableWidget as much as I want and provide different name and role value on each widget.
Column(
children: <Widget>[
MyReusableWidget('Nikola Tesla', 'Owner'), //Input the name and role variable when you call the widget
MyReusableWidget('Albert Einstein', 'Developer'),
MyReusableWidget('Isaac Newton', 'Technician'),
],
),
Result:
And that's it.
You can store any kind of data-type on it (String, int, double, etc).
I hope it will be helpful.
I've been trying to make the TextFormField ('email:') appear in my Simulator, but it's not appearing in my Simulator as following:
However when I make changes to any other things, it does change, so the Simulator is not a problem.
This is my login_page.dart file:
import 'package:flutter/material.dart';
class LoginPage extends StatefulWidget{
#override
State createState() => new LoginPageState();
}
class LoginPageState extends State<LoginPage>{
#override
Widget build(BuildContext context){
return new Scaffold(
appBar: AppBar(
title: new Text("SMART ID", textAlign: TextAlign.center, style: TextStyle(fontFamily: 'Open Sans', fontWeight: FontWeight.bold)),
leading: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
"assets/arrowPNG.png",
scale: 8.0,
)
)
),
backgroundColor: Colors.transparent,
body: Stack(
children: <Widget>[
Container(
alignment: Alignment.center,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/background.png'),
fit: BoxFit.cover,
),
),
),
Positioned(
width: MediaQuery.of(context).size.width,
top: MediaQuery.of(context).size.width * 0.30,
child: Container(
margin: EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset('assets/arrowPNG.png', scale: 2.5),
SizedBox(height: 20,),
Text("SMARTID", style: TextStyle(
fontSize: 30, color: Colors.black, fontFamily: 'Open Sans', fontWeight: FontWeight.bold,
),
),
Text("Attendance & Wallet Monitoring", style: TextStyle(
fontSize: 16, color: Colors.black, fontFamily: 'Open Sans', fontWeight: FontWeight.normal,
)
)
],
),
),
),
Positioned(
width: MediaQuery.of(context).size.width,
top: MediaQuery.of(context).size.width * 0.85,
child: Container(
margin: EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Version 1.0", style: TextStyle(
fontSize: 16, color: Colors.black, fontFamily: 'Open Sans', fontWeight: FontWeight.normal,
)
)
],
)
)
)
],
),
);
}
}
class LoginForm extends StatefulWidget{
#override
LoginFormState createState(){
return LoginFormState();
}
}
class LoginFormState extends State<LoginForm>{
final formKey = GlobalKey<FormState>();
String _username, _password;
#override
Widget build(BuildContext context){
body: Card(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Form(
key: formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextFormField(
decoration: InputDecoration(
labelText: 'Username:'
),
validator: (input) => !input.contains('0') ? 'Username cannot be blank' : null,
onSaved: (input) => _username = input,
),
],
),
),
),
);
}
}
How do I resolve this? Thanks in advance!
You are right, Simulator is not a problem. The problem is in your code. You have correctly created the LoginPage. To correct the LoginForm widget, in your LoingFormState's build function replace:
body: Card(
// your usual code that you have above
)
with
return Card(
// your usual code that you have above
)
Also you have not used the LoginForm Widget in the LoginPage, and that is the reason the form is not visible. Simply, creating a widget doesn't include the widget on any screen, you have to use the widget.
You can do that by adding the widget inside the body section of LoginPageState's build function. To use the widget type
body: Stack(
children: <Widget>[
// your other widgets
LoginForm(),
]
)
like you do for any other widget.
This should solve your problem
I'm just getting started with Flutter.
What is the recommended way to layout a list of cards on a screen?
Some cards will have only contain a single object as a line of text, but others that contain multiple objects as lines of text should also have a header within the card.
For example, here is a mock-up that I drew that I'm trying to accomplish.
Flutter doesn't like a ListView inside a Card. It generates the following errors:
I/flutter (13243): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (13243): The following assertion was thrown during performResize():
I/flutter (13243): Vertical viewport was given unbounded height.
I/flutter (13243): Viewports expand in the scrolling direction to fill their container.In this case, a vertical
I/flutter (13243): viewport was given an unlimited amount of vertical space in which to expand. This situation
I/flutter (13243): typically happens when a scrollable widget is nested inside another scrollable widget.
I/flutter (13243): If this widget is always nested in a scrollable widget there is no need to use a viewport because
I/flutter (13243): there will always be enough vertical space for the children. In this case, consider using a Column
I/flutter (13243): instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size
I/flutter (13243): the height of the viewport to the sum of the heights of its children.
With #aziza's help, I banged out the following code with provides a base layout very close to what I mocked up, but I have a couple of questions:
Is this the most efficient use of nested widgets?
Is there any way to set a global font size so that I don't have to set it on every Text widget?
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My Layout',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'App Bar Title'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List itemList = [
'Card Text 2 Line 1',
'Card Text 2 Line 2',
'Card Text 2 Line 3',
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Sub Title',
style: TextStyle(
fontSize: 25.0,
),
),
],
),
),
Row(
children: [
Expanded(
child: Card(
shape: RoundedRectangleBorder(
side: BorderSide(
width: 3.0,
),
),
margin: EdgeInsets.all(15.0),
color: Colors.grey,
elevation: 10.0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Card 1 Text',
style: TextStyle(
fontSize: 25.0,
),
),
),
),
),
],
),
Row(
children: [
Expanded(
child: Card(
shape: RoundedRectangleBorder(
side: BorderSide(
width: 3.0,
),
),
margin: EdgeInsets.all(15.0),
color: Colors.grey,
elevation: 10.0,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Card 2 Header',
style: TextStyle(
fontSize: 25.0,
),
),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: List.generate(
itemList.length,
(i) => Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
itemList[i],
style: TextStyle(
fontSize: 25.0,
),
),
),
),
),
],
),
),
),
],
),
Row(
children: [
Expanded(
child: Card(
shape: RoundedRectangleBorder(
side: BorderSide(
width: 3.0,
),
),
margin: EdgeInsets.all(15.0),
color: Colors.grey,
elevation: 10.0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Card 3 Text',
style: TextStyle(
fontSize: 25.0,
),
),
),
),
),
],
)
],
),
),
);
}
}
CardModel: Represents each list item, which contains an optional header and list of strings. Building ListView: If header field is persent it is added in a column, then the list of strings of the card are added to the above column as well. At the end these individually created cards are wrapped as a list and displayed inside the ListView.
import 'package:flutter/material.dart';
void main() => runApp(
new MaterialApp(
debugShowCheckedModeBanner: false,
home: new CardsDemo(),
),
);
class CardsDemo extends StatefulWidget {
#override
_CardsDemoState createState() => new _CardsDemoState();
}
class _CardsDemoState extends State<CardsDemo> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Cards'),
),
body: new Column(
children: <Widget>[
new Center(
child: new Padding(
padding: const EdgeInsets.all(15.0),
child: new Text(
'Sub Title',
style:
new TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
),
),
),
new Expanded(
child: new ListView(
children: _buildCards(),
padding: const EdgeInsets.all(8.0),
),
),
],
),
);
}
Widget _buildCard(CardModel card) {
List<Widget> columnData = <Widget>[];
if (card.isHeaderAvailable) {
columnData.add(
new Padding(
padding: const EdgeInsets.only(bottom: 8.0, left: 8.0, right: 8.0),
child: new Text(
card.headerText,
style: new TextStyle(fontSize: 24.0, fontWeight: FontWeight.w500),
),
),
);
}
for (int i = 0; i < card.allText.length; i++)
columnData.add(
new Text(card.allText[i], style: new TextStyle(fontSize: 22.0),),
);
return new Card(
child: new Padding(
padding: const EdgeInsets.symmetric(vertical: 15.0),
child: Column(children: columnData),
),
);
}
List<Widget> _buildCards() {
List<Widget> cards = [];
for (int i = 0; i < sampleCards.length; i++) {
cards.add(_buildCard(sampleCards[i]));
}
return cards;
}
}
class CardModel {
final String headerText;
final List<String> allText;
final bool isHeaderAvailable;
CardModel(
{this.headerText = "", this.allText, this.isHeaderAvailable = false});
}
List<CardModel> sampleCards = [
new CardModel(allText: ["Card 1 Text"]),
new CardModel(
isHeaderAvailable: true,
headerText: "Card 2 Header",
allText: ["Card 2 Text Line 1", "Card 2 Text Line 2"]),
new CardModel(allText: ["Card 3 Text"]),
];