Flutter Firebase Realtime Database.Streambuilder and listview.builder returns error Index out of range: index should be less - flutter

i am using Flutter and Firebase to build an order app.I'm using Realtime Database and a streambuilder to fetch the data and every update and listview.builder to portray them.
When i display the data works fine but the problem is that when i am trying to expand the data in the RTDB i'm getting this error
Another exception was thrown: RangeError (index): Index out of range: index should be less than 22: 22.
I'm trying to expand the data on another page.Sorry if my question is a bit of a crap i am asking for the first time
Scaffold(
body: StreamBuilder(
stream: ref.onValue,
builder: (context, snapshot) {
if(
snapshot.hasData &&
snapshot.data != null &&
(snapshot.data! as DatabaseEvent).snapshot.children !=
null){
List<Orderlist> listorder = [];
final myorders = snapshot.data!.snapshot.children;
myorders.forEach((numoftable) {
count+=1;
String payment_state = '';
String payment_method = '';
List<Order> orders=[];
final number_of_orders = numoftable.children.length;
numoftable.children.forEach((order) {
if(order.key=='payment_state') payment_state=order.value.toString();
if(order.key=='payment_method') payment_method=order.value.toString();
List<Orderitem> orderitems = [];
final order_id = order.key.toString();
// print(order_id);
if(order_id.length<=3){
final node = order.value as Map<dynamic,dynamic>?;
String temp_pending='';
String temp_payment='';
String customer_uid='';
node!.forEach((keys,values) {
// orderitem.name = element;
if(keys!='description' && keys!='customer_uid'){
final value = values as Map<String,dynamic>;
String price='';
String description='';
String number_of_appereance='';
value.forEach((key, value) {
if(key=='price') price=value.toString();
if(key=='description') description=value;
if(key=='number of appereances') number_of_appereance = value.toString();
});
final orderitem = Orderitem(name: keys,price: price,description: description,number_of_appereance: number_of_appereance);
orderitems.add(orderitem);
}
if(keys=='description'){
temp_pending = values.toString();
}
if(keys=='customer_uid'){
customer_uid=values.toString();
}
},);
final nextorder = Order(number_of_table: int.tryParse(numoftable.key.toString()),
items: orderitems,order_ids: order_id,customer_uid: customer_uid,
pending: temp_pending,);
orders.add(nextorder);
}
});
final current_index = int.parse(numoftable.key.toString())-1;
`your text`
if(temp_length.isEmpty || count<=myorders.length){
temp_length.insert(current_index, orders.length);
}
else if(temp_length[current_index]<orders.length ){
temp_length[current_index]= orders.length;
ref.child(numoftable.key.toString()).update({'payment_state':'Not payed'});
ref.child(numoftable.key.toString()).update({'payment_method':'Cash'});
}
final nextorderlist = Orderlist(
orderlist: orders,
number_of_table: numoftable.key.toString(),
payment_state: payment_state,
payment_method: payment_method,
number_of_orders: number_of_orders);
// print(nextorder.order_ids);
listorder.add(nextorderlist);
// ref.child(numoftable.key.toString()).update({'check':'false'});
},
);
return Column(
children: [
GeneralSettings(),
Flexible(
child: GridView.builder(
shrinkWrap: true,
itemCount: listorder.length ,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemBuilder: (context, index) {
return _listoforders(listorder, index,);
},
),
),
],
);
}else if(snapshot.connectionState==ConnectionState.waiting){
Center(child: CircularProgressIndicator(),);
}
else if(snapshot.hasError){
return Text('Error');
}
return Text('Error');
}
),
);
}
Widget _listoforders(List<Orderlist> listoforders,int index) {
return GestureDetector(
onTap: (){
orders.clear();
listoforders[index].orderlist!.forEach((element) { orders.add(element); });
context.goNamed('Details');
},
child: Container(
color:listoforders[index].payment_state=='None' ? Colors.lightBlue : (listoforders[index].payment_state=='Not payed') ? Colors.red : Colors.green,
child: Column(
children: [
ListTile(title: Text(listoforders[index].number_of_table.toString()),
subtitle: listoforders[index].payment_state=='None' ? Icon(Icons.no_food) : listoforders[index].payment_state=='Not payed' ? Icon(Icons.money_off) : Text('Payed'),
trailing: IconButton(onPressed: () {
listoforders[index].orderlist!.forEach((element) {
setState(() {
temp_length[index]=0;
ref.child(listoforders[index].number_of_table.toString()).child(element.order_ids!).remove();
ref.child(listoforders[index].number_of_table.toString()).update({'payment_state':'None'});
ref.child(listoforders[index].number_of_table.toString()).update({'payment_method':'None'});
delete(element.customer_uid!);
});
});
}, icon: Icon(Icons.delete)),
leading: (listoforders[index].payment_method=='None' ) ? Text('No payment method') : (listoforders[index].payment_method=='With card' ) ? Icon(Icons.credit_card) : Icon(Icons.money_rounded),),
Flexible(
child: ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: listoforders[index].orderlist!.length,
itemBuilder: (context, current_index) {
final current_order = listoforders[index].orderlist![current_index];
return Container(
color: current_order.pending=='Unchecked' ? Colors.red : (current_order.pending=='pending') ? Colors.amber : Colors.green,
child: ListTile(
onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context)=>OrderSettings(order: current_order))),
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(current_order.order_ids!),
],
),
subtitle: Text(current_order.pending!),
trailing: current_order.pending=='Unchecked' ? IconButton(onPressed: () => setState(() {
ref.child(current_order.number_of_table.toString()).child(current_order.order_ids!).update({"description":"pending"});
}) , icon: Icon(Icons.alarm_add)) :
current_order.pending=='pending' ? IconButton(onPressed: () => setState(() {
ref.child(current_order.number_of_table.toString()).child(current_order.order_ids!).update({"description":"Done"});
}) , icon: Icon(Icons.pending_actions)) : Icon(Icons.check),
leading: IconButton(onPressed:() {
ref.child(current_order.number_of_table.toString()).child(current_order.order_ids!).remove();
} ,
icon:Icon(Icons.delete) ,),
),
);
},),
),
],
),
),
);}
}
Future delete(String uid) async{
final doc = FirebaseFirestore.instance.collection('Customers').doc(uid);
await doc.update({'order':''});
}
I am updating the RTDB on this page
class UpdatePanel extends StatefulWidget {
String? name;
bool check;
int? tables;
UpdatePanel({super.key,this.name,required this.check, this.tables});
#override
State<UpdatePanel> createState() => _UpdatePanelState();
}
class _UpdatePanelState extends State<UpdatePanel> {
late DatabaseReference ref;
TextEditingController namecontroller = TextEditingController();
TextEditingController number_of_tables = TextEditingController();
#override
void initState() {
// TODO: implement initState
ref=FirebaseDatabase.instance.ref().child(widget.name!);
super.initState();
}
#override
Widget build(BuildContext context) {
print(widget.name);
print(widget.tables);
Size size = MediaQuery.of(context).size;
final futurefiles = FirebaseStorage.instance.ref().child('${widget.name}/');
return AlertDialog(
title: Text(widget.check? 'Update businness name':'Update tables number'),
content: Container(
height: size.height*0.3,
child: SingleChildScrollView(
child: Column(children: [
widget.check ?
Textwidget(controller: namecontroller, hinttext: 'Update name', labeltext: 'Name', icon: Icon(Icons.business_center), color: Colors.black) :
Textwidget(controller: number_of_tables, hinttext: 'Update number of tables', labeltext: 'Number of tables', icon: Icon(Icons.table_bar), color: Colors.black),
SizedBox(height: size.height*0.05,),
ElevatedButton.icon(onPressed: () {
setState(() {
DatabaseManager(displayName: widget.name).settabledata(int.parse(number_of_tables.text.trim()));
createQrcodes();
resetRTDB();
(context as Element).reassemble();
Navigator.pop(context);
});
}, icon: Icon(Icons.update), label: Text('Update'))
]),
),
),
actions: [
OutlinedButton(onPressed: () => Navigator.pop(context), child: Text('Close'))
],
);
}
void resetRTDB() async{
for(int i=widget.tables!+1;i<=int.parse(number_of_tables.text.trim());i++){
await ref.child('${i}').set({"payment_state":"None","payment_method":"None",});
}
}
Future<Uint8List> toQrImageData(String text) async {
try {
final image = await QrPainter(
data: text,
version: QrVersions.auto,
gapless: false,
color: Colors.black,
emptyColor: Colors.white,
).toImage(300);
final a = await image.toByteData(format: ImageByteFormat.png);
return a!.buffer.asUint8List();
} catch (e) {
throw e;
}
}
Future createQrcodes() async{
for(int i=widget.tables!+1;i<=int.parse(number_of_tables.text.trim());i++){
final path = '${widget.name!.trim()}/${i}';
final ref = FirebaseStorage.instance.ref().child(path);
final file = await toQrImageData(widget.name!.trim().toLowerCase()+' '+'${i}');
ref.putData(file,SettableMetadata(contentType: 'image/png'));
}
}
}

this is where your error occurs
void resetRTDB() async{
for(int i=widget.tables!+1;i<=int.parse(number_of_tables.text.trim());i++){
await ref.child('${i}').set({"payment_state":"None","payment_method":"None",});
}
after getting all the data and it tries to get new data by adding 1 in every time ,change try changing your logic here

Related

Flutter: Bad state Error: cannot get a field on a DocumentSnapshotPlatform which does not exist

I'm new to Flutter and getting this issue.
Trying to develop a social media app which includes a chat feature. However, it says DocumentSnapshot is not exist.
Of course I understood that one thing is missing, it is clear. But I couldn't understand what is that missing thing and how to solve it.
I examined a lot of posts about this but I couldn't solve my issue. There is no misspelling between Cloud Firestore and my code. I couldn't understand am I missing key or something like this?
It looks like this
Sometimes it also can not upload the profile picture of person.
Here are my codes,
Thanks for helping.
I got this error when I try to type a message:
class Conversation extends StatefulWidget {
final String userId;
final String chatId;
const Conversation({required this.userId, required this.chatId});
#override
_ConversationState createState() => _ConversationState();
}
class _ConversationState extends State<Conversation> {
FocusNode focusNode = FocusNode();
ScrollController scrollController = ScrollController();
TextEditingController messageController = TextEditingController();
bool isFirst = false;
String? chatId;
#override
void initState() {
super.initState();
scrollController.addListener(() {
focusNode.unfocus();
});
print(widget.chatId);
if (widget.chatId == 'newChat') {
isFirst = true;
}
chatId = widget.chatId;
messageController.addListener(() {
if (focusNode.hasFocus && messageController.text.isNotEmpty) {
setTyping(true);
} else if (!focusNode.hasFocus ||
(focusNode.hasFocus && messageController.text.isEmpty)) {
setTyping(false);
}
});
}
setTyping(typing) {
//here
UserViewModel viewModel =
Provider.of<UserViewModel>(context, listen: false);
viewModel.setUser();
//here
var user = Provider.of<UserViewModel>(context, listen: false).user;
Provider.of<ConversationViewModel>(context, listen: false)
.setUserTyping(widget.chatId, user, typing);
}
#override
Widget build(BuildContext context) {
UserViewModel viewModel =
Provider.of<UserViewModel>(context, listen: false);
viewModel.setUser();
var user = Provider.of<UserViewModel>(context, listen: true).user;
return Consumer<ConversationViewModel>(
builder: (BuildContext context, viewModel, Widget? child) {
return Scaffold(
key: viewModel.scaffoldKey,
appBar: AppBar(
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.keyboard_backspace,
),
),
elevation: 0.0,
titleSpacing: 0,
title: buildUserName(),
),
body: Container(
height: MediaQuery.of(context).size.height,
child: Column(
children: [
Flexible(
child: StreamBuilder<QuerySnapshot>(
stream: messageListStream(widget.chatId),
builder: (context, snapshot) {
if (snapshot.hasData) {
//snapshot.hasData
//print(snapshot.data);
print(viewModel);
List messages = snapshot.data!.docs;
viewModel.setReadCount(
widget.chatId, user, messages.length);
return ListView.builder(
controller: scrollController,
padding: EdgeInsets.symmetric(horizontal: 10.0),
itemCount: messages.length,
reverse: true,
itemBuilder: (BuildContext context, int index) {
Message message = Message.fromJson(
messages.reversed.toList()[index].data(),
);
print(message.content);
print(message.senderUid);
print(message.time);
print(message.type);
return ChatBubble(
message: '${message.content}',
time: message.time!,
isMe: message.senderUid == user!.uid,
type: message.type!,
);
},
);
} else {
return Center(child: circularProgress(context));
}
},
),
),
Align(
alignment: Alignment.bottomCenter,
child: BottomAppBar(
elevation: 10.0,
child: Container(
constraints: BoxConstraints(maxHeight: 100.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
IconButton(
icon: Icon(
CupertinoIcons.photo_on_rectangle,
color: Theme.of(context).colorScheme.secondary,
),
onPressed: () => showPhotoOptions(viewModel, user),
),
Flexible(
child: TextField(
controller: messageController,
focusNode: focusNode,
style: TextStyle(
fontSize: 15.0,
color:
Theme.of(context).textTheme.headline6!.color,
),
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
enabledBorder: InputBorder.none,
border: InputBorder.none,
hintText: "Type your message",
hintStyle: TextStyle(
color: Theme.of(context)
.textTheme
.headline6!
.color,
),
),
maxLines: null,
),
),
IconButton(
icon: Icon(
Ionicons.send,
color: Theme.of(context).colorScheme.secondary,
),
onPressed: () {
if (messageController.text.isNotEmpty) {
sendMessage(viewModel, user);
}
},
),
],
),
),
),
)
],
),
),
);
});
}
_buildOnlineText(
var user,
bool typing,
) {
if (user.isOnline) {
if (typing) {
return "typing...";
} else {
return "online";
}
} else {
return 'last seen ${timeago.format(user.lastSeen.toDate())}';
}
}
buildUserName() {
return StreamBuilder(
stream: usersRef.doc('${widget.userId}').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
DocumentSnapshot documentSnapshot =
snapshot.data as DocumentSnapshot<Object?>;
UserModel user = UserModel.fromJson(
documentSnapshot.data() as Map<String, dynamic>,
);
return InkWell(
child: Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 10.0, right: 10.0),
child: Hero(
tag: user.email!,
child: CircleAvatar(
radius: 25.0,
backgroundImage: CachedNetworkImageProvider(
'${user.photoUrl}',
),
),
),
),
SizedBox(width: 10.0),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'${user.username}',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15.0,
),
),
SizedBox(height: 5.0),
StreamBuilder(
stream: chatRef.doc('${widget.chatId}').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
DocumentSnapshot? snap =
snapshot.data as DocumentSnapshot<Object?>;
Map? data = snap.data() as Map<dynamic, dynamic>?;
Map? usersTyping = data?['typing'] ?? {};
return Text(
_buildOnlineText(
user,
usersTyping![widget.userId] ?? false,
),
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 11,
),
);
} else {
return SizedBox();
}
},
),
],
),
),
],
),
onTap: () {},
);
} else {
return Center(child: CircularProgressIndicator());
}
},
);
}
showPhotoOptions(ConversationViewModel viewModel, var user) {
showModalBottomSheet(
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
),
builder: (context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Text("Camera"),
onTap: () {
sendMessage(viewModel, user, imageType: 0, isImage: true);
},
),
ListTile(
title: Text("Gallery"),
onTap: () {
sendMessage(viewModel, user, imageType: 1, isImage: true);
},
),
],
);
},
);
}
sendMessage(ConversationViewModel viewModel, var user,
{bool isImage = false, int? imageType}) async {
String msg;
if (isImage) {
msg = await viewModel.pickImage(
source: imageType!,
context: context,
chatId: widget.chatId,
);
} else {
msg = messageController.text.trim();
messageController.clear();
}
Message message = Message(
content: '$msg',
senderUid: user?.uid,
type: isImage ? MessageType.IMAGE : MessageType.TEXT,
time: Timestamp.now(),
);
if (msg.isNotEmpty) {
if (isFirst) {
print("FIRST");
String id = await viewModel.sendFirstMessage(widget.userId, message);
setState(() {
isFirst = false;
chatId = id;
});
} else {
viewModel.sendMessage(
widget.chatId,
message,
);
}
}
}
Stream<QuerySnapshot> messageListStream(String documentId) {
return chatRef
.doc(documentId)
.collection('messages')
.orderBy('time')
.snapshots();
}
}
Also here is the ViewModel codes if I did something wrong here:
class ConversationViewModel extends ChangeNotifier {
GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
ChatService chatService = ChatService();
bool uploadingImage = false;
final picker = ImagePicker();
File? image;
sendMessage(String chatId, Message message) {
chatService.sendMessage(
message,
chatId,
);
}
Future<String> sendFirstMessage(String recipient, Message message) async {
String newChatId = await chatService.sendFirstMessage(
message,
recipient,
);
return newChatId;
}
setReadCount(String chatId, var user, int count) {
chatService.setUserRead(chatId, user, count);
}
setUserTyping(String chatId, var user, bool typing) {
chatService.setUserTyping(chatId, user, typing);
}
pickImage({int? source, BuildContext? context, String? chatId}) async {
PickedFile? pickedFile = source == 0
? await picker.getImage(
source: ImageSource.camera,
)
: await picker.getImage(
source: ImageSource.gallery,
);
if (pickedFile != null) {
CroppedFile? croppedFile = await ImageCropper().cropImage(
sourcePath: pickedFile.path,
aspectRatioPresets: [
CropAspectRatioPreset.square,
CropAspectRatioPreset.ratio3x2,
CropAspectRatioPreset.original,
CropAspectRatioPreset.ratio4x3,
CropAspectRatioPreset.ratio16x9
],
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Crop image',
toolbarColor: Theme.of(context!).appBarTheme.backgroundColor,
toolbarWidgetColor: Theme.of(context).iconTheme.color,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false,
),
IOSUiSettings(
minimumAspectRatio: 1.0,
),
],
);
Navigator.of(context).pop();
if (croppedFile != null) {
uploadingImage = true;
image = File(croppedFile.path);
notifyListeners();
showInSnackBar("Uploading image...", context);
String imageUrl = await chatService.uploadImage(image!, chatId!);
return imageUrl;
}
}
}
void showInSnackBar(String value, context) {
ScaffoldMessenger.of(context).removeCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(value),
),
);
}
}
Here is the ChatService code:
class ChatService {
FirebaseStorage storage = FirebaseStorage.instance;
sendMessage(Message message, String chatId) async {
//will send message to chats collection with the usersId
await chatRef.doc("$chatId").collection("messages").add(message.toJson());
//will update "lastTextTime" to the last time a text was sent
await chatRef.doc("$chatId").update({"lastTextTime": Timestamp.now()});
}
Future<String> sendFirstMessage(Message message, String recipient) async {
User user = firebaseAuth.currentUser!;
DocumentReference ref = await chatRef.add({
'users': [recipient, user.uid],
});
await sendMessage(message, ref.id);
return ref.id;
}
Future<String> uploadImage(File image, String chatId) async {
Reference storageReference =
storage.ref().child("chats").child(chatId).child(uuid.v4());
UploadTask uploadTask = storageReference.putFile(image);
await uploadTask.whenComplete(() => null);
String imageUrl = await storageReference.getDownloadURL();
return imageUrl;
}
//determine if a user has read a chat and updates how many messages are unread
setUserRead(String chatId, User user, int count) async {
DocumentSnapshot snap = await chatRef.doc(chatId).get();
Map reads = snap.get('reads') ?? {};
reads[user.uid] = count;
await chatRef.doc(chatId).update({'reads': reads});
}
//determine when a user has start typing a message
setUserTyping(String chatId, User user, bool userTyping) async {
DocumentSnapshot snap = await chatRef.doc(chatId).get();
Map typing = snap.get('typing');
typing[user.uid] = userTyping;
await chatRef.doc(chatId).update({
'typing': typing,
});
}
}

I want to filter using CheckboxListTile in flutter but i have not showing any reflection of filtering in listview when i use Alert dialog?

I filter the one litview builder list to another checkbox list and this is working, but when i add this CheckboxListTile in Alert dialog when no filter reflection showing.
I used StatefulBuilder also but is not useful to filtering listview.
[This is first link to show Product list data][1]
This is second link of filter list
I am stuck in how to one data filter to another item filter that availiable in Alert dialog.
This is Api link
const String baseUrl = "https://run.mocky.io/v3/";
const String productDataUrl = baseUrl + "4ecbd2ea-a725-438b-b8fc-da8fc08bc875";
const String productCategoryDataUrl =
baseUrl + "0595387e-732e-47cf-9675-244fed9fc014";
This is product model class that listview model that we want to filter
class ProductDataModel {
int? productId;
String? productName;
int? productPrice;
int? productKG;
String? productCategoryId;
ProductDataModel(
{this.productId,
this.productName,
this.productPrice,
this.productKG,
this.productCategoryId});
ProductDataModel.fromJson(Map<String, dynamic> json) {
productId = json['ProductId'];
productName = json['ProductName'];
productPrice = json['ProductPrice'];
productKG = json['ProductKG'];
productCategoryId = json['ProductCategoryId'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['ProductId'] = this.productId;
data['ProductName'] = this.productName;
data['ProductPrice'] = this.productPrice;
data['ProductKG'] = this.productKG;
data['ProductCategoryId'] = this.productCategoryId;
return data;
}
}
This ProductCategory Model class for using filter and this model class
data in CheckboxTile
class ProductCategoryDataModel {
int? productCategoryId;
String? productCategoryName;
bool? isChecked=false;
ProductCategoryDataModel(
{this.productCategoryId, this.productCategoryName, this.isChecked});
ProductCategoryDataModel.fromJson(Map<String, dynamic> json) {
productCategoryId = json['ProductCategoryId'];
productCategoryName = json['ProductCategoryName'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['ProductCategoryId'] = this.productCategoryId;
data['ProductCategoryName'] = this.productCategoryName;
return data;
}
}
This is code of showing listview and filter data using
checkboxlisttile that data in Alert dialog .
import 'dart:convert';
import 'dart:developer';
import 'package:dummy_checkbox_filter_list/commons/api_url.dart';
import 'package:dummy_checkbox_filter_list/model/product_category_data_model.dart';
import 'package:dummy_checkbox_filter_list/model/product_data_model.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<ProductDataModel> productDataList = [];
Set<ProductDataModel> productDataListDisplay = {};
List<ProductCategoryDataModel> productCategoryDataList = [];
List<ProductCategoryDataModel> selectProductCategoryDataList = [];
ScrollController scrollController = ScrollController();
bool isShowLoader = false;
getProductList() async {
try {
setState(() {
isShowLoader = true;
});
final response = await http.get(Uri.parse(productDataUrl));
log("Response URL=> ${response.toString()}");
if (response.statusCode == 200) {
var decode = jsonDecode(response.body);
log("Response Body=> ${decode.toString()}");
for (int i = 0; i < decode.length; i++) {
productDataList.add(ProductDataModel.fromJson(decode[i]));
}
setState(() {
isShowLoader = false;
});
return productDataList;
} else {
setState(() {
isShowLoader = false;
});
throw "Unable to retrieve product data.";
}
} catch (e) {
setState(() {
isShowLoader = false;
});
print('Something went wrong.');
}
}
getProductCategoryList() async {
try {
setState(() {
isShowLoader = true;
});
final response = await http.get(Uri.parse(productCategoryDataUrl));
log("Response URL=> ${response.toString()}");
if (response.statusCode == 200) {
var decode = jsonDecode(response.body);
log("Response Body=>${decode.toString()}");
for (int i = 0; i < decode.length; i++) {
productCategoryDataList
.add(new ProductCategoryDataModel.fromJson(decode[i]));
}
setState(() {
isShowLoader = false;
});
return productCategoryDataList;
} else {
setState(() {
isShowLoader = false;
});
throw "Unable to retrieve product data.";
}
} catch (e) {
setState(() {
isShowLoader = false;
});
print('Something went wrong.');
}
}
#override
void initState() {
getProductList();
getProductCategoryList();
super.initState();
}
#override
Widget build(BuildContext context) {
filterProduct(productDataList);
return Scaffold(
body: SafeArea(
child: isShowLoader == false
? SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
titlePadding: EdgeInsets.zero,
backgroundColor: Color(0xFF242424),
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: Icon(
Icons.close,
color: Colors.white,
size: 25,
))
],
),
contentPadding: EdgeInsets.zero,
content: Container(
padding: EdgeInsets.all(5),
width: double.maxFinite,
child: ListView(
padding: EdgeInsets.all(8.0),
children: [
Text(
"dfff "+productCategoryDataList[0].isChecked.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 16),
),
...productCategoryDataList
.map((e) => CheckboxListTile(
controlAffinity:
ListTileControlAffinity
.leading,
title: Text(
"${e.productCategoryName}",
style: TextStyle(
color: Colors.white,
fontSize: 16),
),
value: e.isChecked,
selected:
selectProductCategoryDataList
.contains(e),
onChanged: (val) {
print("val: "+val.toString());
setState(() {
e.isChecked = val;
selectProductCategoryDataList
.contains(e)
? selectProductCategoryDataList
.remove(e)
: selectProductCategoryDataList
.add(e);
print(
"_isChecked: ${e.isChecked}");
});
},
))
],
),
),
);
},
);
});
},
style: ElevatedButton.styleFrom(
primary: Colors.black,
onPrimary: Colors.white,
minimumSize: Size(
MediaQuery.of(context).size.width * 0.30,
MediaQuery.of(context).size.height * 0.05)),
child: Text(
"Filter",
style: TextStyle(fontSize: 15),
),
),
Container(
child: ListView.builder(
itemCount: productDataListDisplay.length,
shrinkWrap: true,
controller: scrollController,
itemBuilder: (context, index) {
return Card(
child: Container(
padding: EdgeInsets.only(top: 15, bottom: 15),
color: (index % 2 == 0)
? Colors.grey.shade100
: Colors.white,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(productDataListDisplay
.elementAt(index)
.productId
.toString()),
Center(
child: Text(
productDataListDisplay
.elementAt(index)
.productName
.toString(),
),
),
Center(
child: Text(
"${productDataListDisplay.elementAt(index).productKG.toString()} KG",
),
),
Center(
child: Text(
"${productDataListDisplay.elementAt(index).productCategoryId.toString()}",
),
),
],
),
),
);
},
),
),
],
),
)
: Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue)),
),
),
);
}
void filterProduct(allProducts) {
productDataListDisplay.clear();
if (selectProductCategoryDataList != null &&
selectProductCategoryDataList.isNotEmpty) {
final List<int> idsOfSelectedCategories = selectProductCategoryDataList
.map((category) => category.productCategoryId!)
.toList();
print("idsOfSelectedCategories=> $idsOfSelectedCategories");
Set<ProductDataModel> storesInSelectedCategories =
getStoresFromSelectedCategories(allProducts, idsOfSelectedCategories);
setState(() {
productDataListDisplay.addAll(storesInSelectedCategories);
print(allProducts.length);
print(storesInSelectedCategories.length);
});
} else {
setState(() {
productDataListDisplay.addAll(allProducts);
});
}
}
Set<ProductDataModel> getStoresFromSelectedCategories(
List<ProductDataModel> allProducts, List<int> idsOfSelectedCategories) {
Set<ProductDataModel> allProductsFromCategory = {};
for (var categoryId in idsOfSelectedCategories) {
var productMatched = allProducts
.where((store) => store.productCategoryId!
.split(" ")
.contains(categoryId.toString()))
.toList();
print("Stores Matched runtime=>${productMatched.runtimeType}");
allProductsFromCategory.addAll(productMatched);
}
return allProductsFromCategory;
}
}
Add .then((value) {if (mounted) {setState(() {});}}); to showdialog so that state gets refreshed when alertdialog closes.
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<ProductDataModel> productDataList = [];
Set<ProductDataModel> productDataListDisplay = {};
List<ProductCategoryDataModel> productCategoryDataList = [];
List<ProductCategoryDataModel> selectProductCategoryDataList = [];
ScrollController scrollController = ScrollController();
bool isShowLoader = false;
getProductList() async {
try {
setState(() {
isShowLoader = true;
});
final response = await http.get(Uri.parse(productDataUrl));
log("Response URL=> ${response.toString()}");
if (response.statusCode == 200) {
var decode = jsonDecode(response.body);
log("Response Body=> ${decode.toString()}");
for (int i = 0; i < decode.length; i++) {
productDataList.add(ProductDataModel.fromJson(decode[i]));
}
setState(() {
isShowLoader = false;
});
return productDataList;
} else {
setState(() {
isShowLoader = false;
});
throw "Unable to retrieve product data.";
}
} catch (e) {
setState(() {
isShowLoader = false;
});
print('Something went wrong.');
}
}
getProductCategoryList() async {
try {
setState(() {
isShowLoader = true;
});
final response = await http.get(Uri.parse(productCategoryDataUrl));
log("Response URL=> ${response.toString()}");
if (response.statusCode == 200) {
var decode = jsonDecode(response.body);
log("Response Body=>${decode.toString()}");
for (int i = 0; i < decode.length; i++) {
productCategoryDataList
.add(new ProductCategoryDataModel.fromJson(decode[i]));
}
setState(() {
isShowLoader = false;
});
return productCategoryDataList;
} else {
setState(() {
isShowLoader = false;
});
throw "Unable to retrieve product data.";
}
} catch (e) {
setState(() {
isShowLoader = false;
});
print('Something went wrong.');
}
}
#override
void initState() {
getProductList();
getProductCategoryList();
super.initState();
}
#override
Widget build(BuildContext context) {
filterProduct(productDataList);
return Scaffold(
body: SafeArea(
child: isShowLoader == false
? SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
titlePadding: EdgeInsets.zero,
backgroundColor: const Color(0xFF242424),
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: const Icon(
Icons.close,
color: Colors.white,
size: 25,
))
],
),
contentPadding: EdgeInsets.zero,
content: Container(
padding: EdgeInsets.all(5),
width: double.maxFinite,
child: ListView(
padding: EdgeInsets.all(8.0),
children: [
Text(
"dfff ${productCategoryDataList[0].isChecked}",
style: const TextStyle(
color: Colors.white,
fontSize: 16),
),
...productCategoryDataList
.map((e) => CheckboxListTile(
controlAffinity:
ListTileControlAffinity
.leading,
title: Text(
"${e.productCategoryName}",
style: const TextStyle(
color: Colors.white,
fontSize: 16),
),
value: e.isChecked,
selected:
selectProductCategoryDataList
.contains(e),
onChanged: (val) {
print("val: $val");
setState(() {
e.isChecked = val;
selectProductCategoryDataList
.contains(e)
? selectProductCategoryDataList
.remove(e)
: selectProductCategoryDataList
.add(e);
print(
"_isChecked: ${e.isChecked}");
});
},
))
],
),
),
);
},
);
}).then((value) {
if (mounted) {
setState(() {});
}
});
},
style: ElevatedButton.styleFrom(
primary: Colors.black,
onPrimary: Colors.white,
minimumSize: Size(
MediaQuery.of(context).size.width * 0.30,
MediaQuery.of(context).size.height * 0.05)),
child: const Text(
"Filter",
style: TextStyle(fontSize: 15),
),
),
Container(
child: ListView.builder(
itemCount: productDataListDisplay.length,
shrinkWrap: true,
controller: scrollController,
itemBuilder: (context, index) {
return Card(
child: Container(
padding: EdgeInsets.only(top: 15, bottom: 15),
color: (index % 2 == 0)
? Colors.grey.shade100
: Colors.white,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(productDataListDisplay
.elementAt(index)
.productId
.toString()),
Center(
child: Text(
productDataListDisplay
.elementAt(index)
.productName
.toString(),
),
),
Center(
child: Text(
"${productDataListDisplay.elementAt(index).productKG.toString()} KG",
),
),
Center(
child: Text(
"${productDataListDisplay.elementAt(index).productCategoryId.toString()}",
),
),
],
),
),
);
},
),
),
],
),
)
: Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue)),
),
),
);
}
void filterProduct(allProducts) {
productDataListDisplay.clear();
if (selectProductCategoryDataList != null &&
selectProductCategoryDataList.isNotEmpty) {
final List<int> idsOfSelectedCategories = selectProductCategoryDataList
.map((category) => category.productCategoryId!)
.toList();
print("idsOfSelectedCategories=> $idsOfSelectedCategories");
Set<ProductDataModel> storesInSelectedCategories =
getStoresFromSelectedCategories(allProducts, idsOfSelectedCategories);
setState(() {
productDataListDisplay.addAll(storesInSelectedCategories);
print(allProducts.length);
print(storesInSelectedCategories.length);
});
} else {
setState(() {
productDataListDisplay.addAll(allProducts);
});
}
}
Set<ProductDataModel> getStoresFromSelectedCategories(
List<ProductDataModel> allProducts, List<int> idsOfSelectedCategories) {
Set<ProductDataModel> allProductsFromCategory = {};
for (var categoryId in idsOfSelectedCategories) {
var productMatched = allProducts
.where((store) => store.productCategoryId!
.split(" ")
.contains(categoryId.toString()))
.toList();
print("Stores Matched runtime=>${productMatched.runtimeType}");
allProductsFromCategory.addAll(productMatched);
}
return allProductsFromCategory;
}
}

RenderFlex children have non-zero flex but incoming height constraints are unbounded in flatter

I have a page code written in an android studio. On this page, I display a list of objects, as well as a widget to search for these objects. When I clicked on the search widget, I had the following problem: "The following statement was thrown during layout:
RenderFlex is overcrowded 31 pixels below.
The corresponding widget that caused the errors was: "But then I found the answer to this question and added" SingleChildScrollView ".
But then I had this problem: "RenderFlex have non-zero flexibility, but the input height limits are unlimited." . And I can't solve it in any way. I will be grateful for your help. Here is my code:
import 'package:flutter/material.dart';
import 'package:flutter_app_seals/model/post/form_unseals.dart';
import 'package:flutter_app_seals/model/post/form_seals.dart';
import 'package:flutter_app_seals/model/setting/globalvar.dart' as global;
import 'dart:async';
import 'dart:io';
import 'dart:convert';
void main() => runApp(JsonParseObjectSts_UN());
class JsonParseObjectSts_UN extends StatefulWidget {
JsonParseObjectSts_UN() : super();
#override
_JsonParseObjectsState createState() => _JsonParseObjectsState();
}
class _JsonParseObjectsState extends State <StatefulWidget> {
List<UserDetails> _searchResult = [];
List<UserDetails> _userDetails = [];
TextEditingController controller = new TextEditingController();
final String url = global.urlVar ;
// Get json result and convert it to model. Then add
Future<Null> getUserDetails() async {
HttpClient client = new HttpClient();
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
final request = await client
.getUrl(Uri.parse(url))
.timeout(Duration(seconds: 5));
HttpClientResponse response = await request.close();
var responseBody = await response.transform(utf8.decoder).join();
final responseJson = json.decode(responseBody);
setState(() {
for (Map user in responseJson) {
_userDetails.add(UserDetails.fromJson(user));
}
});
}
#override
void initState() {
super.initState();
getUserDetails();
}
Widget _buildUsersList() {
return new ListView.builder(
itemCount: _userDetails.length,
itemBuilder: (context, index) {
return new Card(
color: (_userDetails[index].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_userDetails[index].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_userDetails[index].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _userDetails[index].sealed) {
global.nameObj = _userDetails[index].name,
global.sealsNumb = _userDetails[index].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _userDetails[index].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchResults() {
return new ListView.builder(
itemCount: _searchResult.length,
itemBuilder: (context, i) {
return new Card(
color: (_searchResult[i].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_searchResult[i].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_searchResult[i].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _searchResult[i].sealed) {
global.nameObj = _searchResult[i].name,
global.sealsNumb = _searchResult[i].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _searchResult[i].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchBox() {
return new Padding(
padding: const EdgeInsets.all(8.0),
child: new Card(
child: new ListTile(
leading: new Icon(Icons.search),
title: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Пошук', border: InputBorder.none),
onChanged: onSearchTextChanged,
),
trailing: new IconButton(
icon: new Icon(Icons.cancel),
onPressed: () {
controller.clear();
onSearchTextChanged('');
},
),
),
),
);
}
Widget _buildBody() {
return new Scaffold(
body:Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.white],
begin: Alignment.topCenter,
end: Alignment.bottomCenter),
),
child: SingleChildScrollView(
child:Column(
children: <Widget>[
new Container(
color: Theme.of(context).primaryColor, child: _buildSearchBox()),
new Expanded(
child: _searchResult.length != 0 || controller.text.isNotEmpty
? _buildSearchResults()
: _buildUsersList()),
],
),
),
),
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: _buildBody()
);
}
onSearchTextChanged(String text) async {
_searchResult.clear();
if (text.isEmpty) {
setState(() {});
return;
}
_userDetails.forEach((userDetail) {
if (userDetail.name.contains(text) ) _searchResult.add(userDetail);
});
setState(() {});
}
}
class UserDetails {
final String name, seal_number,sealed;
UserDetails({this.name, this.sealed, this.seal_number});
factory UserDetails.fromJson(Map<String, dynamic> json) {
return new UserDetails(
sealed: json['sealed'],
name: json['name'],
seal_number: json['seal_number'],
);
}
}
My scrin:
My scrin when I want to use search:

how to increase the size of the window with the search result in flutter?

I have a page code written in an android studio. On this page, I display a list of objects, as well as a widget to search for these objects. When I clicked on the search widget,my list of objects is shrinking, and it is almost invisible (it is at the top). Can this be fixed somehow so that it can be seen on the whole page ??
import 'package:flutter/material.dart';
import 'package:flutter_app_seals/model/post/form_unseals.dart';
import 'package:flutter_app_seals/model/post/form_seals.dart';
import 'package:flutter_app_seals/model/setting/globalvar.dart' as global;
import 'dart:async';
import 'dart:io';
import 'dart:convert';
void main() => runApp(JsonParseObjectSts_UN());
class JsonParseObjectSts_UN extends StatefulWidget {
JsonParseObjectSts_UN() : super();
#override
_JsonParseObjectsState createState() => _JsonParseObjectsState();
}
class _JsonParseObjectsState extends State <StatefulWidget> {
List<UserDetails> _searchResult = [];
List<UserDetails> _userDetails = [];
TextEditingController controller = new TextEditingController();
final String url = global.urlVar ;
// Get json result and convert it to model. Then add
Future<Null> getUserDetails() async {
HttpClient client = new HttpClient();
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
final request = await client
.getUrl(Uri.parse(url))
.timeout(Duration(seconds: 5));
HttpClientResponse response = await request.close();
var responseBody = await response.transform(utf8.decoder).join();
final responseJson = json.decode(responseBody);
setState(() {
for (Map user in responseJson) {
_userDetails.add(UserDetails.fromJson(user));
}
});
}
#override
void initState() {
super.initState();
getUserDetails();
}
Widget _buildUsersList() {
return new ListView.builder(
itemCount: _userDetails.length,
itemBuilder: (context, index) {
return new Card(
color: (_userDetails[index].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_userDetails[index].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_userDetails[index].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _userDetails[index].sealed) {
global.nameObj = _userDetails[index].name,
global.sealsNumb = _userDetails[index].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _userDetails[index].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchResults() {
return new ListView.builder(
itemCount: _searchResult.length,
itemBuilder: (context, i) {
return new Card(
color: (_searchResult[i].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_searchResult[i].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_searchResult[i].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _searchResult[i].sealed) {
global.nameObj = _searchResult[i].name,
global.sealsNumb = _searchResult[i].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _searchResult[i].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchBox() {
return new Padding(
padding: EdgeInsets.all(7.0),
child: new Card(
child: new ListTile(
leading: new Icon(Icons.search),
title: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Пошук', border: InputBorder.none),
onChanged: onSearchTextChanged,
),
trailing: new IconButton(
icon: new Icon(Icons.cancel),
onPressed: () {
controller.clear();
onSearchTextChanged('');
},
),
),
),
);
}
Widget _buildBody() {
return new Scaffold(
body:Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.white],
begin: Alignment.topCenter,
end: Alignment.bottomCenter),
),
child:Column(
children: <Widget>[
new Expanded( flex: 1, child: _buildSearchBox()),
new Expanded(flex:8,
child: _searchResult.length != 0 || controller.text.isNotEmpty
? _buildSearchResults()
: _buildUsersList()),
],
),
),
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: _buildBody()
);
}
onSearchTextChanged(String text) async {
_searchResult.clear();
if (text.isEmpty) {
setState(() {});
return;
}
_userDetails.forEach((userDetail) {
if (userDetail.name.contains(text) ) _searchResult.add(userDetail);
});
setState(() {});
}
}
class UserDetails {
final String name, seal_number,sealed;
UserDetails({this.name, this.sealed, this.seal_number});
factory UserDetails.fromJson(Map<String, dynamic> json) {
return new UserDetails(
sealed: json['sealed'],
name: json['name'],
seal_number: json['seal_number'],
);
}
}
My page:
My page with search:
I have looked at your code several times, I just noticed a small error.
For the results of your searches, you try to display the "List" of searches in a ListView.builder, which is in a column in the parent container does not have a defined height.
Solution: Set a height for the main container and the problem will be solved

Flutter List View Data Duplication when I do setState and pagination with StreamBuilder

I am implementation the list data from API to show in list view. There I am using Streambuiler and pull to refresh library for scrolling changes. I set the new data from API to local list inside StreamBuilder. Every time when I made setState for state changes. The StreamBuilder rebuild and setting data again. Then my list was duplicated, I do not know yet what's wrong with my code. I am developing the App with flutter recently. Please check my code what is wrong in there. 🙏🙏🙏
class OrderListScreen extends StatefulWidget {
#override
_OrderListScreenState createState() => _OrderListScreenState();
}
class _OrderListScreenState extends State<OrderListScreen> {
String showingFromDate, showingToDate;
OrderBloc _orderBloc;
OrderListOb _orderListOb = OrderListOb();
int paginationPage = 0;
DateTime fromDate, toDate;
List<Orders> _orderList = [];
var _refreshController = RefreshController();
#override
void initState() {
super.initState();
_orderBloc = OrderBloc();
initDate();
fetchAPI();
}
#override
void dispose() {
super.dispose();
_orderBloc.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: defaultAppBar("Order List Screen", showBackArrow: false),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
textView("From Date", isBold: true),
textView("To Date", isBold: true),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ActionChip(
padding: EdgeInsets.all(4.0),
avatar: Icon(
Icons.calendar_today_sharp,
color: Colors.white,
size: 18,
),
backgroundColor: PRIMARY_COLOR,
label: textView(showingFromDate, textColor: Colors.white),
onPressed: () {
_selectDate(context, isFromDate: true);
},
),
ActionChip(
padding: EdgeInsets.all(4.0),
avatar: Icon(
Icons.calendar_today_sharp,
color: Colors.white,
size: 18,
),
backgroundColor: PRIMARY_COLOR,
label: textView(showingToDate, textColor: Colors.white),
onPressed: () {
_selectDate(context, isFromDate: false);
},
),
],
),
StreamBuilder(
stream: _orderBloc.orderListStream(),
initialData:
BaseResponse(data: null, message: MsgState.loading),
builder: (BuildContext context, AsyncSnapshot snapshot) {
BaseResponse ob = snapshot.data;
if (ob.message == MsgState.loading) {
return Center(
child: Container(
child: CircularProgressIndicator(),
),
);
} else if (ob.message == MsgState.data ) {
_orderListOb = OrderListOb();
_orderListOb = ob.data;
_orderList.addAll(_orderListOb.result.orders);
return buildListView();
} else {
return handleErrorWidget(ob.data);
}
},
),
],
),
));
}
Widget buildListView() {
return Container(
height: 450,
child: SmartRefresher(
enablePullUp: _orderListOb.result.orders.length > 9,
enablePullDown: true,
onRefresh: () {
print("Pull To Refresh");
},
onLoading: () {
paginationPage = _orderListOb.result.pagination.nextId;
fetchAPI(); //Do pagination
},
controller: _refreshController,
child: ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: _orderList.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () {
context.navigateName("order_detail", data: {
'isAcceptOrder': true,
'order_id': _orderList[index].id
});
},
child: orderItemWidget(_orderList[index],
isAcceptedOrder: false));
}),
),
);
}
void fetchAPI() {
_orderBloc.getOrderList(
serviceId: ServiceTypes.AIRCON_SERVICE.value,
fromDate: DateUtil.requestDateFormat(fromDate.toString()),
toDate: DateUtil.requestDateFormat(toDate.toString()),
page: paginationPage);
}
void initDate() {
showingFromDate = DateUtil.covertDate(DateUtil.getCurrentDate().toString());
showingToDate = DateUtil.covertDate(DateUtil.getCurrentDate().toString());
fromDate = DateUtil.getCurrentDate();
toDate = DateUtil.getCurrentDate();
}
void resetData() {
print("Clear");
paginationPage = 0;
_orderList.clear();
}
_selectDate(BuildContext context, {bool isFromDate = true}) async {
final DateTime picked = await showDatePicker(
context: context,
initialDate: isFromDate ? fromDate : toDate, // Refer step 1
firstDate: DateTime(2000),
lastDate: DateTime(2025),
);
if (picked != null)
setState(() {
if (isFromDate) {
showingFromDate = DateUtil.covertDate(picked.toString());
fromDate = picked;
} else {
showingToDate = DateUtil.covertDate(picked.toString());
toDate = picked;
}
resetData();
fetchAPI();
});
}
}
The problem is that you're doing _orderList.addAll(_orderListOb.result.orders); . Instead, you should clean the list before or just _orderList=_orderListOb.result.orders;
Check for existence the value before adding to list, if list doesnt contain the value then add like this:
if(!_orderList.contains(_orderListOb.result.orders))
_orderList.addAll(_orderListOb.result.orders);
I hope it will work!