how to iterate the list and build tree - flutter

i have two cards in in row and each time row creates with two card i have data in my list and when list iterates it creates same name of card
i have an array of subcatextra and SubCategory class that have data i want to show first object name sub.name on first card and on second card name should be the next object of subcatextra list , i don't know how to achieve this please ** help me ***
here is my code
ListView(
children: subcatextra.map<Widget>((SubCategory sub)
{
return Row(
children: <Widget>[
Container(
width: (MediaQuery
.of(context)
.size
.width / 2) - 20,
height: 90,
child: InkWell(
onTap: (){},
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
elevation: 1,
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
height: 70,
width: 80,
child: Image.network(
"https://smartbasket.pk/image/cache/data/Bazaarapna/dairy%20product/Haleeb%20Milk%20%E2%80%93%2001%20Litre%20(Pack%20of%2012)-500x500.jpg",
fit: BoxFit.cover)),
Container(margin: EdgeInsets.only(right: 15),
child: Text(sub.name, style: TextStyle(fontSize: 17),))
],
),
),
),
),
),
Spacer(),
Container(
width: (MediaQuery
.of(context)
.size
.width / 2) - 20,
height: 90,
child: Card(
elevation: 1,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
height: 70,
width: 80,
child: Image.network(
"https://smartbasket.pk/image/cache/data/Bazaarapna/dairy%20product/Haleeb%20Milk%20%E2%80%93%2001%20Litre%20(Pack%20of%2012)-500x500.jpg",
fit: BoxFit.cover)),
Text(sub.name, style: TextStyle(fontSize: 17),)
],
),
),
)
],
);
}).toList()
);

You can use a ListView.builder, create two variables for each object and assign them according the index being even or odd. Bellow follows a complete example that you cant test at DartPad:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: CardListView()));
}
class CardListView extends StatefulWidget {
#override
_CardListViewState createState() => _CardListViewState();
}
class _CardListViewState extends State<CardListView> {
#override
void initState() {
super.initState();
}
List<String> list = [
'name1',
'name2',
'name3',
'name4',
'name5',
'name6',
'name7',
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Title")),
body: new ListView.builder(
itemCount: list.length,
itemBuilder: (BuildContext ctxt, int index) {
String firstCellContent = '';
String secondCellContent = '';
if (index % 2 == 0) {
firstCellContent = list[index];
if (index + 1 < list.length - 1) {
secondCellContent = list[index + 1];
} else {
secondCellContent = '';
}
}
return Row(
children: <Widget>[
Container(
padding: EdgeInsets.all(15),
child: new Text(
firstCellContent,
),
),
Container(
padding: EdgeInsets.all(15),
child: new Text(
secondCellContent,
),
),
],
);
},
),
);
}
}

Related

Flutter: responsive height and width

in my flutter code below i'm suffering from height and width problem which appears different on each device, for ex in my below code i set a background image and it appears on half screen if i didn't set a height, and ofc this height appears different on each device.
also in child: Image.asset( object["placeImage"], fit: BoxFit.cover,width: 280,height: 180,) i wanted the image to appear one size on all devices without setting a specific height and width.. is there a way to do this in flutter?
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:localize_and_translate/localize_and_translate.dart';
import 'package:menu_app/About.dart';
import 'package:menu_app/Drinks.dart';
import 'package:flutter/gestures.dart';
class FoodDetailsPage extends StatefulWidget {
final String pageId;
//The string of each meal will be passed when calling this page.
FoodDetailsPage({required this.pageId});
#override
_FoodDetailsPageState createState() => _FoodDetailsPageState();
}
class _FoodDetailsPageState extends State<FoodDetailsPage> {
late Future<List<Widget>> myCreateList;
#override
void initState() {
super.initState();
myCreateList = createList();
//THIS IS NECESSARY TO AVOID THE FUTUREBUILDER FROM FIRING EVERYTIME THE PAGE REBUILDS.
// You can check more at
// https://stackoverflow.com/questions/57793479/flutter-futurebuilder-gets-constantly-called
}
Future<List<Widget>> createList() async {
List<Widget> items = <Widget>[];
String dataString = await rootBundle.loadString(translator.translate(
"assets/${widget.pageId}.json")); //view JSON file depending on pageId
List<dynamic> dataJSON = jsonDecode(dataString);
dataJSON.forEach((object) {
String finalString = "";
List<dynamic> dataList = object["placeItems"];
dataList.forEach((item) {
finalString = finalString + item + " | ";
});
items.add(Padding(
padding: EdgeInsets.all(2.0),
child: Container(
decoration: BoxDecoration(
color: Color.fromRGBO(255, 255, 255, 0.7),
borderRadius: BorderRadius.all(Radius.circular(10.0)),
boxShadow: [
BoxShadow(
color: Colors.black12, spreadRadius: 2.0, blurRadius: 5.0),
]),
margin: EdgeInsets.all(5.0),
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
child: Image.asset(
object["placeImage"], // also here i need to set a astatic height and width on each device
fit: BoxFit.cover,
width: 280,
height: 180,
),
),
SizedBox(
width: 250,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
translator.translate(object["placeName"]),
style: GoogleFonts.elMessiri(
textStyle: TextStyle(
fontSize: 15.0, color: Colors.black54)),
),
// Padding(
// padding: const EdgeInsets.only(top: 2.0, bottom: 2.0),
// child: Text(
// finalString,
// overflow: TextOverflow.ellipsis,
// style: TextStyle(
// fontSize: 12.0,
// color: Colors.black54,
// ),
// maxLines: 1,
// ),
// ),
Text(
translator.translate(" ${object["minOrder"]} IQD"),
style: TextStyle(fontSize: 12.0, color: Colors.black54),
)
],
),
),
)
],
),
),
));
});
return items;
}
Widget build(BuildContext context) {
// ignore: unused_local_variable
var size = MediaQuery.of(context).size;
var screenHeight = MediaQuery.of(context).size.height;
var screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
appBar: AppBar(
backgroundColor: HexColor("#242424"),
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
iconSize: 20.0,
onPressed: () {
Navigator.pop(context);
},
),
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
"assets/images/logo.png",
fit: BoxFit.contain,
height: 40,
),
],
),
),
body: SafeArea(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min, // set min
children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
"assets/images/backg.png", // i have to set a static height for each device to get the full backfround
),
fit: BoxFit.fill)),
height: 3000,
width: screenWidth,
child: FutureBuilder<List<Widget>>(
initialData: [Text("")],
future: myCreateList,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Text(translator.translate("Loading"));
if (snapshot.hasError) {
return Text("Error ${snapshot.error}");
}
if (snapshot.hasData) {
return Padding(
padding: EdgeInsets.all(8.0),
child: GridView.count(
childAspectRatio: 1, // items' width/height
crossAxisCount: 2,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: [
// ignore: sdk_version_ui_as_code
...?snapshot.data,
],
));
} else {
return CircularProgressIndicator();
}
}),
)
],
),
)),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => About()),
);
},
backgroundColor: Colors.black,
child: Icon(
MdiIcons.information,
color: Colors.white,
)),
);
}
}
if you want you image to same size in every device wrap it with a container and give static height and width use the fit property according to your needs but if you want the size of the image should change according to device height and width you can use media query for that ....for eg
Container(
color: Colors.yellow,
height: MediaQuery.of(context).size.height * 0.65,
width: MediaQuery.of(context).size.width,
)
put your image in child parameter ......
let me know if this help

Countdown in a ListView (Flutter)

I would like to find a solution to create countdowns from a date and put them in a ListView. I hope this does not slow down the application too much when using it.
I already have a code I want to keep, it's a RecyclerView with images and text.
Here's the code, if you need anything else I'll send it to you.
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import '../recyclerview/data.dart';
import 'package:watch/constants.dart';
class ListViewExample extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return new ListViewExampleState(
);
}
}
class ListViewExampleState extends State<ListViewExample>{
List<Container> _buildListItemsFromItems(){
int index = 0;
return item.map((item){
var container = Container(
decoration: index % 2 == 0?
new BoxDecoration(color: const Color(0xFFFFFFFF)):
new BoxDecoration(
color: const Color(0xFFFAFAF5)
),
child: new Row(
children: <Widget>[
new Container(
margin: new EdgeInsets.all(5.0),
child: new CachedNetworkImage(
imageUrl: item.imageURL,
width: 200.0,
height: 100.0,
fit: BoxFit.cover,
),
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: const EdgeInsets.only(bottom: 75.0 ),
child: Text(
item.title,
style: kItemTitle,
),
),
Container(
padding: const EdgeInsets.only(left: 15.0),
child:Text(
item.description,
style: kItemDescription,
),
),
]),
)
],
)
);
index = index + 1;
return container;
}).toList();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text('Accueil', style: kAppBarStyle,),
backgroundColor: Colors.white,
elevation: 0,
),
body: ListView(
children: _buildListItemsFromItems(),
),
);
}
}
Thank you!
Update : to add the countdown look this post :Date Countdown Timer
and for the lazy loading, I have changed my ListView to a ListView.builder
Is is suggested to use Listview.builder and not just put a list into ListView if you need lazy loading.
https://flutter.dev/docs/cookbook/lists/long-lists
Replace the ListView to ListView.builder.
ListView.builder(
itemCount: // items.length
itemBuilder: (buildContext, index) {}, // define what Widget for each index
)
Here is the sample code from yours. index is already exist in itemBuilder function.
...
body: ListView.builder(
itemCount: items.length,
itemBuilder: (buildContext, index) {
return Container(
decoration: index % 2 == 0
? new BoxDecoration(color: const Color(0xFFFFFFFF))
: new BoxDecoration(color: const Color(0xFFFAFAF5)),
child: new Row(
children: <Widget>[
new Container(
margin: new EdgeInsets.all(5.0),
child: new CachedNetworkImage(
imageUrl: item.imageURL,
width: 200.0,
height: 100.0,
fit: BoxFit.cover,
),
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: const EdgeInsets.only(bottom: 75.0),
child: Text(
items[index].title,
),
),
Container(
padding: const EdgeInsets.only(left: 15.0),
child: Text(
items[index].description,
),
),
],
),
)
],
),
);
},
),
...

How to make infinity scroll layout in flutter? (Updated)

I'm trying to make listview using data from REST API, the position is below my image , but the layout reach its limit, so i can't create it , and showing this error
here my code, (Updated Code)
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:schoolofparentingalfa/assets/color/color.dart';
class Home extends StatefulWidget {
#override
Home2 createState() => Home2();
}
class Home2 extends State<Home> {
var colorsop = new Colorsop();
var apiconfig = new ApiConfig();
var apiClient = new ApiClient();
#override
void initState() {
super.initState();
}
//To call list from api
Future<List<Artikel>> getNews() async {
// future is used to handle the error when calling api > Future + async or await
var data = await http.get(
'https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=c4349a84570648eaa7be3cd673cc262b');
var jsonData = json.decode(data.body);
var newsData =
jsonData['articles']; //to retrieve data from articles array of api
List<Artikel> news = []; // create array
for (var data in newsData) {
//assign data into News model array list from articles array of api
Artikel newsItem = Artikel(
data['title'], data['description'], data['urlToImage']);
news.add(newsItem);
}
return news;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(children: <Widget>[
Positioned(
top: 0,
child: Container(
height: 100,
width: MediaQuery.of(context).size.width,
color: Colors.yellow[800],
child: Align(
alignment: Alignment.center,
child: Text("Halo, Selamat Datang", style: TextStyle(color: Colors.white, fontSize: 25),))),
),
Positioned(
top: 90,
bottom: 0,
right: 0,
left: 0,
child: Container(
width: MediaQuery.of(context).size.width,
height: 600,
decoration: BoxDecoration(
color: Colors.white,
),
child: GridView.count(
crossAxisCount: 1,
children: [
Container( // Container 1
child: Row(
children: <Widget>[
Image.asset(
'lib/assets/image/kelas_online.png',
height: 120,
width: 150,
),
Image.asset(
'lib/assets/image/tanyaahli.png',
height: 120,
width: 150,
),
],
),
),
Container( // Container 2
child: Row(
children: <Widget>[
Image.asset(
'lib/assets/image/workshop_online.png',
height: 120,
width: 150,
),
Image.asset(
'lib/assets/image/MitraSekolah.png',
height: 120,
width: 150,
),
],
),
),
Container( //Container 3
margin: EdgeInsets.only(top: 15, bottom: 30, left: 20),
padding: EdgeInsets.symmetric(horizontal: 15),
child: FutureBuilder(
future: getNews(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
//snapshot is same with response
if (snapshot.data == null) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
// to retrieve data as all array indexes
itemBuilder: (BuildContext context, int index) {
// is same with holder
return InkWell(
// Inkwell is used to apply card view
onTap: () {
Artikel news = new Artikel(snapshot.data[index].post_link, snapshot.data[index].description, snapshot.data[index].post_image);//is used to onclick
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => new Details(news: news)
));
},
child: Card(
child: Row(
children: <Widget>[
Container(
width: 120.0,
height: 110.0,
child: ClipRRect(
//for corner radius
borderRadius:
BorderRadius.all(Radius.circular(8)),
//to retrieve image from array
child: snapshot.data[index].post_image == null
? Image.network(
'https://cdn2.vectorstock.com/i/1000x1000/70/71/loading-icon-load-icon-wait-for-a-wait-please-wait-vector-24247071.jpg')
: Image.network(
snapshot.data[index].post_image,
width: 100,
fit: BoxFit.fill,
),
),
),
Expanded(
child: ListTile(
//include title and subtitle
title: Text(snapshot.data[index].post_title),
subtitle: Text(snapshot.data[index].post_link == null
? 'Unknown Author'
: snapshot.data[index].post_link),
),
)
],
),
),
);
},
);
}
},
),
),
],
),
)
)
],),
);
}
}
}
class Details extends StatelessWidget{
final Artikel news;
Details({this.news}); // create constructor
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: Column(
children: <Widget>[
Stack( //little same with expanded
children: <Widget>[
Container(
height: 400,
child: Image.network('${this.news.post_image}',
fit: BoxFit.fill,),
),
AppBar(
backgroundColor: Colors.transparent,
leading: InkWell(
child: Icon(Icons.arrow_back_ios),
onTap: () => Navigator.pop(context),
),
elevation: 0,
)
],
),
Padding(
padding: const EdgeInsets.all(8),
child: Column(
children: <Widget>[
SizedBox( // for title
height: 10,
),
Text(
'${this.news.post_title}',
style: TextStyle(
color: Colors.black87,
fontWeight: FontWeight.bold,
fontSize: 20,
letterSpacing: 0.2,
wordSpacing: 0.6
),
),
SizedBox( // for description
height: 20,
),
Text(
this.news.post_link,
style: TextStyle(
color: Colors.black54,
fontSize: 16,
letterSpacing: 0.2,
wordSpacing: 0.3
),
)
],
),
)
],
),
),
),
);
}
}
class Artikel {
final String post_title;
final String post_link;
final String post_image;
//Alt+insert > constructor
Artikel(this.post_title, this.post_link, this.post_image);
}
Can anyone help me?
Updated Screenshot .............................................................................
you can replace the code and check
return Scaffold(
body: Stack(children: <Widget>[
Positioned(
top: 0,
child: Container(
height: 100,
width: MediaQuery.of(context).size.width,
color: Colors.yellow[800],
child: Align(
alignment: Alignment.center,
child: Text("Halo, Selamat Datang", style: TextStyle(color: Colors.white, fontSize: 25),))),
),
Positioned(
top: 90,
bottom: 0,
right: 0,
left: 0,
child: Container(
width: MediaQuery.of(context).size.width,
height: 600,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topLeft:Radius.circular(20), topRight:Radius.circular(20)) ),
child:
GridView.count(
crossAxisCount: 2,
children: List.generate(5, (index) {
return Padding(
padding: const EdgeInsets.all(24.0),
child: GridTile(child: Image.network("https://upload.wikimedia.org/wikipedia/commons/6/6d/Good_Food_Display_-_NCI_Visuals_Online.jpg"),),
);
}) ,),)
)
],),
);

how to execute the API when the textfield is filled BLOC FLUTTER?

how to execute the API when the textfield is filled. so when the textfield is filled it starts executing the API.
I've tried making a check function that works if the textfield is not null then I can only start the API execution. in the following ways:
in the block I make a check function to check whether the textfield (_prefix) is filled or not but this function is an error when called in inStState in the UI section.
BLOC :
class DenomPulsaBloc {
final _repository = EresidenceRepository();
final _prefix = BehaviorSubject<String>();
SharedPreferences sPrefs;
final BehaviorSubject<List<Payload>> _subject = BehaviorSubject<List<Payload>>();
Function(String) get prefix => _prefix.sink.add;
cek() async{
if(_prefix.value.length >= 3) {
denomPulsa();
}else{
print("GAGAL");
}
}
denomPulsa() async{
try{
sPrefs = await SharedPreferences.getInstance();
ListPulsaResponses responses = await _repository.listDenomPulsa(sPrefs.getString("userid"), sPrefs.getString("password"), sPrefs.getString("imei"),
sPrefs.getString("coordinate"), sPrefs.getString("bit61"), sPrefs.getString("bit62"), _prefix.value);
List<Payload> list = responses.data.payload;
_subject.sink.add(list);
print(list);
}catch(e){
print(e.toString());
_subject.sink.add(e);
}
}
dispose(){
_subject.close();
_prefix.close();
}
BehaviorSubject<List<Payload>> get subject => _subject;
}
UI :
class _PulsaPageState extends State<PulsaPage> {
DenomPulsaBloc denomPulsaBloc;
int selectedCard = -1;
#override
void initState() {
super.initState();
denomPulsaBloc = DenomPulsaBloc();
denomPulsaBloc.cek();
}
#override
void dispose() {
denomPulsaBloc.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 2,
child: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.white,
brightness: Brightness.light,
elevation: 0.0,
leading: InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: Icon(
Icons.arrow_back_ios,
color: Colors.black,
size: SizeConfig.texIconSize,
),
),
),
body: SafeArea(
child: Container(
height: SizeConfig.screenHeight,
width: SizeConfig.screenWidth,
padding: EdgeInsets.symmetric(horizontal: SizeConfig.widthMultiplier * 4),
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
child: Text(
'Pulsa',
style: AppTheme.styleSubTitleBoldLarge,
)
),
Container(
margin: EdgeInsets.only(top: SizeConfig.heightMultiplier * 4),
decoration: BoxDecoration(
boxShadow: <BoxShadow>[
BoxShadow(blurRadius: 5.0, color: Colors.black12)
]
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Container(
padding: EdgeInsets.all(SizeConfig.heightMultiplier * 2),
color: Colors.white,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 1,
child:
Container(
child: Icon(Icons.phone_android, color: Colors.green, size: SizeConfig.texIconSize,),
),
),
Expanded(
flex: 9,
child: Container(
margin: EdgeInsets.only(left: SizeConfig.widthMultiplier * 3),
child:Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: Text(
'Number',
style: AppTheme.styleSubTitle,
),
),
Container(
child: Stack(children: <Widget>[
Container(
height: SizeConfig.heightMultiplier * 5.5,
child: TextFormField(
inputFormatters: [
new LengthLimitingTextInputFormatter(13)
],
style: AppTheme.styleSubTitleBlackSmall,
decoration: const InputDecoration(
hintText: '090900909'
),
onChanged: denomPulsaBloc.prefix,
),
),
Align(
alignment: Alignment.centerRight,
child: Container(
alignment: Alignment.centerRight,
height: SizeConfig.texIconSize,
width: SizeConfig.texIconSize,
margin: EdgeInsets.only(right: SizeConfig.widthMultiplier * 9, top: SizeConfig.heightMultiplier * 1.5),
child: Image.asset(
"res/images/xl.png",
fit: BoxFit.fill,
)
),
),
Align(
alignment: Alignment.centerRight,
child: Container(
margin: EdgeInsets.only(top: SizeConfig.heightMultiplier * 1.5),
child: InkWell(
onTap: (){},
child: Icon(
Icons.close,
size: SizeConfig.texIconSize,
),
)
)
)
]),
),
]
),
)
),
],
),
),
),
),
Expanded(
child: Container(
width: SizeConfig.screenWidth,
height: SizeConfig.screenHeight,
child: StreamBuilder(
stream: denomPulsaBloc.subject,
builder: (context, AsyncSnapshot<List<Payload>> snapshot) {
if (snapshot.hasData) {
// print(snapshot.data);
return listDenomPulsa(snapshot);
}else{
Error();
}
return Container();
},
),
),
),
],
),
),
),
),
),
);
}

I want to add a new element after my horizontal listview how can I add it

This is the projected picture that shows how I am able to add an element.
Below is my code in which I want to add an element so that if my list is not present it also shows the element and if it present then the element is the last element.
I have tried this in some different ways.
Can anyone please help me?
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'alllist.dart';
List<Alllist> _alllist = [];
List<Alllist> get alllist => _alllist;
class EduCategory extends StatefulWidget{
final String listcategory;
final int intp;
EduCategory({this.listcategory,this.intp});
#override
EduCategoryState createState() {
return new EduCategoryState();
}
}
class EduCategoryState extends State<EduCategory> {
#override
Widget build(BuildContext context) {
// TODO: implement build
return Container(child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
widget.listcategory,
style: TextStyle(fontWeight: FontWeight.bold),
),
new Row(
children: <Widget>[
new Icon(Icons.play_arrow),
new Text("Watch All", style: TextStyle(fontWeight: FontWeight.bold))
],
)
],
),
Expanded(
child: new Padding(
padding: const EdgeInsets.only(top: 8.0),
child:new StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('all list').where("listcategory",isEqualTo: widget.listcategory).snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) return new Text("no");
if (snapshot.data.documents.length == 0) return InkWell(
child: Stack(
children: <Widget>[
new Container(
width: 80.0,
height: 80.0,
decoration: new BoxDecoration(
shape: BoxShape.rectangle,
border: Border.all(color: Colors.blueGrey),
borderRadius: BorderRadius.circular(5.0),
image: new DecorationImage(
fit: BoxFit.fill,
image: new AssetImage("assets/Plus.png")),
),
margin: const EdgeInsets.symmetric(horizontal: 20.0),
// child: Text(name),
),
Padding(padding: EdgeInsets.only(top: 80.0,left: 20.0),
child: Text("Add Lession",style: TextStyle(fontWeight: FontWeight.bold,color: Colors.blueGrey),),
),
],
),
onTap: (){},
);
return new ListView(
scrollDirection: Axis.horizontal,
children: buildGrid(snapshot.data.documents)
);;
}
),
))
],
),
);
}
List<Widget> buildGrid(List<DocumentSnapshot> documents) {
List<Widget> _gridItems = [];
_alllist.clear();
for (DocumentSnapshot document in documents) {
_alllist.add(Alllist.fromDocument(document));
}
for (Alllist alllist in _alllist) {
_gridItems.add(buildGridItem(alllist));
}
return _gridItems;
}
Widget buildGridItem(Alllist alllist,) {
return widget.intp==0?
InkWell(
child: Stack(
children: <Widget>[
new Container(
width: 80.0,
height: 80.0,
decoration: new BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: Colors.blue,width: 4.0,style: BorderStyle.solid),
image: new DecorationImage(
fit: BoxFit.fill,
image: new NetworkImage(
alllist.imageUrl)),
),
margin: const EdgeInsets.symmetric(horizontal: 20.0),
// child: Text(name),
),
Padding(padding: EdgeInsets.only(top: 80.0,left: 10.0),
child: Text(alllist.title,style: TextStyle(fontWeight: FontWeight.bold,color: Colors.blueGrey),),
),
],
),
onTap: (){},
):new Row(
children: <Widget>[
InkWell(
child: Stack(
children: <Widget>[
new Container(
width: 80.0,
height: 80.0,
decoration: new BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5.0),
image: new DecorationImage(
fit: BoxFit.fill,
image: new NetworkImage(
alllist.imageUrl)),
),
margin: const EdgeInsets.symmetric(horizontal: 20.0),
// child: Text(name),
),
Padding(padding: EdgeInsets.only(top: 80.0,left: 10.0),
child: Text(alllist.title,style: TextStyle(fontWeight: FontWeight.bold,color: Colors.blueGrey),),
),
],
),
onTap: (){},
)
]
);
}
}
You can use the ListView.builder with itemCount as snapshot.data.documents.length + 1.
Code sample:
new StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('all list').where("listcategory",isEqualTo: widget.listcategory).snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) return new Text("no");
var documentsLength = snapshot.data.documents.length;
ListView.builder(itemCount: documentsLength + 1, // +1 for last element
itemBuilder: (context, index) {
if (index == documentsLength) {
//last view which have plus button
} else {
return buildGridItem((Alllist.fromDocument(snapshot.data.documents[index]))
}
});
})
I think that you have to just add condition in itemBuilder checkout in below code;
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final List<int> items=[1,2,3,4,5,6];
#override
Widget build(BuildContext context) {
final title = 'Mixed List';
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Container(
height: 100.0,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: items.length + 1 ,
itemBuilder: (context, index) {
if(index < items.length )
{ return Container(
color: Colors.blue,
width: 100.0,
padding: EdgeInsets.all(8.0),
child: new Center(
child: new Text(index.toString()),
),
);
}
else {
return new Container(
color: Colors.blue,
width: 100.0,
child: new Center(
child: new Text(index.toString() + "differnt"),
),
);
}
},
),
),
),
);
}
}