Related
There is two files that have similar code, it is add and update area feature, that I decide to make it only one, with using condition.
You can see that two features have similar widgets, only different in texts.
Add Area Feature
Update Area Feature
In my case, when user want to adding area, the UI will display add area feature. When user want to updating area, the UI will display update area feature, but it only from one codebase.
Is it possible to make that kind of condition?
Here I copy paste the whole codes of add area feature. I don't have to copy paste update area because it has the similar codes.
class AddAreaItem extends StatefulWidget {
const AddAreaItem({super.key, this.isUpdate = false});
final bool isUpdate;
#override
State<AddAreaItem> createState() => _AddAreaItemState();
}
class _AddAreaItemState extends State<AddAreaItem> {
//--------- selectedCategory_1 variable
String selectedCategoryArea = '';
#override
Widget build(BuildContext context) {
return Container(
height: 366,
width: 514,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
height: 25,
),
SizedBox(
width: 434,
height: 42,
child: Wrap(
alignment: WrapAlignment.spaceBetween,
children: [
Text(
widget.isUpdate ? 'Add Area' : 'Update Area',
style: heading2(
color: ColorName.blackPrimary,
),
),
Padding(
padding: const EdgeInsets.only(top: 10),
child: InkWell(
child: SvgPicture.asset(
Assets.icons.closeIcon.path,
width: 16,
height: 16,
),
onTap: () => {
Navigator.pop(context),
},
),
)
],
),
),
//----------- TextField Code Area dan Category
SizedBox(
width: 435,
child: Wrap(
alignment: WrapAlignment.spaceAround,
children: [
Wrap(
direction: Axis.vertical,
children: [
Text(
'Area Code',
style: body1(
color: ColorName.blackPrimary,
),
),
SizedBox(
height: 10,
),
SizedBox(
width: 126,
height: 60,
child: TextField(
style: body1(color: ColorName.blackPrimary),
cursorColor: ColorName.blackPrimary,
decoration: InputDecoration(
hintText: 'Area Code',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
focusedBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
borderSide: BorderSide(
color: ColorName.grey,
),
),
),
),
),
],
),
Wrap(
direction: Axis.vertical,
children: [
Text(
'Category Area',
style: body1(
color: ColorName.blackPrimary,
),
),
const SizedBox(
height: 10,
),
Container(
width: 288,
height: 56,
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
side: BorderSide(
style: BorderStyle.solid, color: ColorName.grey),
borderRadius: BorderRadius.all(
Radius.circular(10),
),
),
),
child: DropdownButton<String>(
icon: Padding(
padding: const EdgeInsets.only(right: 10, top: 8),
child: SvgPicture.asset(
Assets.icons.dropdownIcon.path,
fit: BoxFit.scaleDown,
),
),
style: body1(color: ColorName.blackPrimary),
items: <String>[
'Block',
'Fining Line',
].map((String value) {
return DropdownMenuItem(
value: value,
child: Text(value),
);
}).toList(),
hint: Padding(
padding: const EdgeInsets.only(top: 8, left: 10),
child: Text(
style: body1(color: ColorName.grey),
selectedCategoryArea.isEmpty
? 'Category Area'
: selectedCategoryArea),
),
borderRadius: BorderRadius.circular(10),
underline: const SizedBox(),
isExpanded: true,
onChanged: (value) {
if (value != null) {
setState(() {
selectedCategoryArea = value;
});
}
},
),
),
],
),
],
),
),
//----------- Tombol Add Area dan Cancel
SizedBox(
width: 425,
child: Wrap(
alignment: WrapAlignment.spaceBetween,
children: [
SizedBox(
width: 183,
height: 60,
child: OutlinedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
side: MaterialStateProperty.all(
const BorderSide(
color: ColorName.darkBlue,
),
),
),
child: Text(
'Cancel',
style: subtitle1(
color: ColorName.darkBlue,
),
),
onPressed: () {
Navigator.pop(context);
},
),
),
//------------- Tombol add area
SizedBox(
width: 183,
height: 60,
child: OutlinedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
ColorName.darkBlue,
),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
side: MaterialStateProperty.all(
const BorderSide(
color: ColorName.darkBlue,
),
),
),
child: Text(
widget.isUpdate ? 'Add Area' : 'Update Area',
style: subtitle1(
color: ColorName.white,
),
),
onPressed: () {
if (widget.isUpdate) {
AddAreaSuccess().showCustomDialog(context);
} else {
UpdateAreaSuccess().showCustomDialog(context);
}
},
),
),
],
),
),
const SizedBox(
height: 25,
),
],
),
);
}
}
Firstly you need to define from where you know that the screen is updating screen or adding screen. I mean like
class AddAreaItem extends StatefulWidget {
final bool isUpdate;
const AddAreaItem({super.key, this.isUpdate=false});//IT MEANS THAT isUpdate is FALSE by default, but you can define it while creating AddAreaItem
...
}
Then in your widgets you can do like this:
Text(
widget.isUpdate?'Update Area':'Add Area',
//if it is inside Stateless widget then you use isUpdate? instead of widget.isUpdate
style: subtitle1(
color: ColorName.white,
),
),
Inside functions like onPressed you can just use like this:
onPressed: (){
if(widget.isUpdating){
AddAreaSuccess().showCustomDialog(context);
}else{...}
}
You can pass those two values in the properties when rendering this widget. Then check if the properties are null then you are trying to add new data. But if those contains the value then its updating the data.
Something like this
class AreaWidget extends StatefulWidget {
const AreaWidget({super.key, this.areaCode, this.areaName});
final int? areaCode;
final String? areaName;
#override
State<AreaWidget> createState() => _AreaWidgetState();
}
class _AreaWidgetState extends State<AreaWidget> {
#override
Widget build(BuildContext context) {
return Container(
child: Text(widget.areaCode == null ? "Add Area" : "Upate Area"),
);
}
}
You can then check value and make the changes according to the value. Even inside the function as well to call the specific add or update related code.
how can I make bottom bar to look same like in image, top corners to be rounded and to icons have the space same like in image.
here is code of bottomMenu bar how is right now.. so basically to have rounded corner and to icon have padding from left and right. but if I add whole BottomNavigationBar in padding then it not move just icons.. hope that somebody can help me to fix this..
Scaffold(
body: _handlePages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: _currentIndex,
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
items: <BottomNavigationBarItem>[
_currentIndex == 0
? BottomNavigationBarItem(
icon: Image.asset(
"assets/images/cam.png",
height: 25,
color: appColorBlue,
),
label: "",
)
: BottomNavigationBarItem(
icon: Image.asset(
"assets/images/cam.png",
height: 25,
color: appColorGrey,
),
label: "",
),
_currentIndex == 1
? BottomNavigationBarItem(
icon: Image.asset(
"assets/images/call_blue.png",
height: 27,
color: appColorBlue,
),
label: "",
)
: BottomNavigationBarItem(
icon: Image.asset(
"assets/images/call_blue.png",
height: 27,
color: appColorGrey,
),
label: "",
),
_currentIndex == 2
? BottomNavigationBarItem(
icon: Image.asset(
"assets/images/chat.png",
height: 27,
color: appColorBlue,
),
label: "",
)
: BottomNavigationBarItem(
icon: Image.asset(
"assets/images/chat.png",
height: 27,
color: appColorGrey,
),
label: "",
),
_currentIndex == 3
? BottomNavigationBarItem(
icon: Container(
height: 30,
width: 30,
child: new Stack(
children: <Widget>[
globalImage.length > 0
? CircleAvatar(
radius: 30,
backgroundImage: NetworkImage(globalImage),
)
: Container(
height: 30,
width: 30,
decoration: BoxDecoration(
color: Colors.grey[400],
shape: BoxShape.circle),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Image.asset(
"assets/images/user.png",
height: 10,
color: Colors.white,
),
)),
],
),
),
// Image.asset(
// "assets/images/settings.png",
// height: 25,
// color: appColorBlue,
// ),
label: "",
)
: BottomNavigationBarItem(
icon: Container(
height: 30,
width: 30,
child: new Stack(
children: <Widget>[
globalImage.length > 0
? CircleAvatar(
radius: 30,
backgroundImage: NetworkImage(globalImage),
)
: Container(
height: 30,
width: 30,
decoration: BoxDecoration(
color: Colors.grey[400],
shape: BoxShape.circle),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Image.asset(
"assets/images/user.png",
height: 10,
color: Colors.white,
),
)),
],
),
),
// Image.asset(
// "assets/images/settings.png",
// height: 25,
// color: appColorGrey,
// ),
label: "",
),
],
),
),
You can create your own bottom nav bar so that you can design it freely.
Sample...
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: List.generate(
100,
(index) => ListTile(
title: Text('TEST $index'),
),
),
),
bottomNavigationBar: const RoundedBottomNavBar(
onTap: print,
children: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.camera_alt)),
BottomNavigationBarItem(icon: Icon(Icons.phone)),
BottomNavigationBarItem(icon: Icon(Icons.send)),
BottomNavigationBarItem(icon: Icon(Icons.circle)),
],
childrenPadding: const EdgeInsets.symmetric(horizontal: 10),
),
);
}
}
class RoundedBottomNavBar extends StatefulWidget {
const RoundedBottomNavBar({
required this.onTap,
required this.children,
this.background = Colors.white,
this.topCornerRadius = 20,
this.childrenPadding = const EdgeInsets.all(0),
});
final ValueChanged<int> onTap;
final List<BottomNavigationBarItem> children;
final Color background;
final double topCornerRadius;
final EdgeInsetsGeometry childrenPadding;
#override
_RoundedBottomNavBarState createState() => _RoundedBottomNavBarState();
}
class _RoundedBottomNavBarState extends State<RoundedBottomNavBar> {
late Radius _topCornerRadius;
int _selectedIndex = 0;
#override
void initState() {
super.initState();
_topCornerRadius = Radius.circular(widget.topCornerRadius);
}
#override
Widget build(BuildContext context) {
int tmpCount = 0;
return Container(
padding: const EdgeInsets.symmetric(vertical: 10),
decoration: BoxDecoration(
color: widget.background,
borderRadius: BorderRadius.only(
topLeft: _topCornerRadius,
topRight: _topCornerRadius,
),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 5,
offset: Offset(0, 3),
),
],
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: widget.children.map((BottomNavigationBarItem item) {
final int index = tmpCount++;
return GestureDetector(
onTap: () {
setState(() => _selectedIndex = index);
widget.onTap(index);
},
child: Opacity(
opacity: _selectedIndex == index ? 1 : 0.3,
child: Padding(
padding: widget.childrenPadding,
child: item.icon,
),
),
);
}).toList(),
),
),
);
}
}
a solution can be adding your custom bottomNvigationBar, playing with the colors and the shadow, also de radius, something like this:
this is the body
Scaffold(
bottomNavigationBar: bottom(),
appBar: AppBar(
title: Center(child: Text("test")),
),
body: Container(),
);
and here is the bottom widget:
Widget bottom() {
return Container(
height: 60, //you can do it with mediaQuery
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black,
blurRadius: 5.0,
spreadRadius: 2.0,
),
],
color: Colors.blue,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(25),
topRight: Radius.circular(25),
)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
GestureDetector(
onTap: () {
print("hello, i press ");
},
child: Icon(
Icons.camera_alt,
size: 35,
),
),
GestureDetector(
onTap: () {
print("hello, i press ");
},
child: Icon(
Icons.phone,
size: 35,
),
),
GestureDetector(
onTap: () {
print("hello, i press ");
},
child: Icon(
Icons.near_me,
size: 35,
)),
],
));
}
here a screenshot of the result:
I'm attempting to create a notification widget with a number overlay.
I've followed the code here to make the widget.
Using this code (not specifying a position), produces the following widget:
Widget iconWidget() {
return Stack(
children: <Widget>[
Center(
child: Container(
child: Icon(
icon,
color: color,
),
)),
Positioned(
child: CircleAvatar(
child: Text('$count',
style: TextStyle(fontSize: 12, color: Colors.white)),
backgroundColor: count == 0 ? Colors.grey : Colors.black,
),
)
],
);
}
However, as soon as I specify a position (right: 0), my widget gets gut off:
Widget iconWidget() {
return Stack(
children: <Widget>[
Center(
child: Container(
child: Icon(
icon,
color: color,
),
)),
Positioned(
right: 0,
child: CircleAvatar(
child: Text('$count',
style: TextStyle(fontSize: 12, color: Colors.white)),
backgroundColor: count == 0 ? Colors.grey : Colors.black,
),
)
],
);
}
My widget is being created as an icon within a tab controller:
Tab(
icon: IconWithCount(
icon: FlutterIcons.heartbeat_faw5s,
color: Colors.red,
count: 5)
.iconWidget(),
),
Full class creating the widget:
class IconWithCount {
final IconData icon;
final int count;
final Color color;
IconWithCount({
this.icon,
this.count,
this.color,
});
Widget iconWidget() {
return Stack(
children: <Widget>[
Center(
child: Container(
child: Icon(
icon,
color: color,
),
)),
Positioned(
right: 0,
child: CircleAvatar(
child: Text('$count',
style: TextStyle(fontSize: 12, color: Colors.white)),
backgroundColor: count == 0 ? Colors.grey : Colors.black,
),
)
],
);
}
}
overflow is Deprecated. Use this:
Stack(
clipBehavior: Clip.none, // <---
children: [],
)
Inside the stack , just add this
overflow: Overflow.visible,
In Flutter I want to create an app bar that looks as follows:
I've easily managed to add the 2 icons on the left and right, but I am struggling to create a rectangle in the middle.
I've tried the following code:
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
leading: IconButton(
icon: Image.asset('assets/images/maps.png'),
onPressed: () => {},
),
title: Expanded( // The bit that's not working. A rectangle that fills the middle area.
child: Container(
color: Colors.blue,
),
),
actions: <Widget>[
IconButton(
icon: Image.asset('assets/images/search.png'),
onPressed: () => {},
),
],
),
);
but I get the following exception:
Expanded widgets must be placed inside Flex widgets.
Expanded(no depth, flex: 1, dirty) has no Flex ancestor at all.
Thanks for the help.
You can achieve this by setting the centerTile attribute of the AppBar to true
Like this
import 'package:flutter/material.dart';
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
centerTitle: true,
leading: IconButton(
icon: Icon(
Icons.location_on,
color: Colors.grey,
),
onPressed: () => {},
),
title: Container(
padding: EdgeInsets.all(10),
child: Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Icon(Icons.refresh),
Expanded(
child: Center(
child: Text("London"),
),
),
Opacity(child: Icon(Icons.refresh), opacity: 0,),
],
),
decoration: BoxDecoration(
color: Colors.grey, borderRadius: BorderRadius.circular(10)),
),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.search,
color: Colors.grey,
),
onPressed: () => {},
),
],
),
);
}
}
The output:
An alternative solution (inspired by #Josteve Adekanbi answer), to create a rectangle that fills the title area is:
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
leading: ...
title: Container(
width: double.infinity,
height: 40,
child: Container(
color: Colors.blue,
),
),
actions: ...
),
);
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);
},
);
}
}