Search results and then disappear using stream - flutter

I was trying o create search engine. It was working well when I had only one stream but I then tried to merge 2 streams now it shows for some milliseconds then disappears. I do not know what can cause that or anything I did wrong
Below is my code
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:tembea/components/search_engine.dart';
import 'package:tembea/screens/user/view_activity.dart';
import 'package:async/async.dart' show StreamGroup;
class SearchDashboard extends StatefulWidget {
const SearchDashboard({Key? key}) : super(key: key);
#override
_SearchDashboardState createState() => _SearchDashboardState();
}
class _SearchDashboardState extends State<SearchDashboard> {
String query = '';
Stream ? streamQuery;
List<Stream<QuerySnapshot>> streams = [];
#override
Widget build(BuildContext context) {
return Column(
children: [
SearchEngine(
onChanged: (value){
setState(() {
if(value.isNotEmpty){
setState(() {
query = value[0].toUpperCase() + value.substring(1);
var firstQuery = FirebaseFirestore.instance.collection('activities')
.where('Type', isGreaterThanOrEqualTo: query)
.where('Type', isLessThan: query + 'z')
.snapshots();
var secondQuery = FirebaseFirestore.instance.collection('activities')
.where('Name', isGreaterThanOrEqualTo: query)
.where('Name', isLessThan: query + 'z')
.snapshots();
streams.add(firstQuery);
streams.add(secondQuery);
streamQuery = StreamGroup.merge(streams);
});
}
});
},
text: query,
),
const SizedBox(
height: 20,
),
const Divider(
height: 20,
color: Colors.green,
),
const SizedBox(
height: 20,
),
streamQuery != null ? StreamBuilder(
stream: streamQuery,
builder:(context, AsyncSnapshot snapshot){
if(snapshot.connectionState == ConnectionState.waiting){
return const Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.green),
),
);
}
final data = snapshot.requireData;
return SizedBox(
height: MediaQuery.of(context).size.height * 0.50,
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: data.size,
itemBuilder: (context, index){
return GestureDetector(
onTap: (){
Navigator.push(context, MaterialPageRoute(builder: (context){
return ViewActivity(activity: data.docs[index]);
}));
},
child: Column(
children: [
Row(
children: [
const Icon(
IconData(0xe567, fontFamily: 'MaterialIcons'),
color: Colors.green,
),
Text(
data.docs[index]['Name'],
style: GoogleFonts.abel(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(
width: 23
),
Text(
data.docs[index]['Type'],
style: GoogleFonts.abel(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.green
),
),
],
),
const SizedBox(
height: 20,
),
],
),
);
}
),
);
}
) : Center(
child: Text(
'Search for Anything',
style: GoogleFonts.aBeeZee(
textStyle:const TextStyle(
fontSize: 22,
color: Colors.white70,
fontWeight: FontWeight.bold
)
),
),
),
],
);
}
}
Please assist me on this. I have been here the entire day trying to search for solution but cannot find anything

Related

RangeError (index): Valid value range is empty: 0

I am trying to display data from an api in a ListView.builder, I want to set the itemCount to 20 but when I do that, before the data is displayed I get the following error RangeError (index): Valid value range is empty: 0 the '0' is incremented in each card until '20'. If anyone can help me, thanks.
import 'dart:typed_data';
import 'package:badges/badges.dart';
import 'package:banner_carousel/banner_carousel.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:kaomini/Pages/accueil.dart';
import 'package:kaomini/Pages/detail_article.dart';
import 'package:kaomini/Pages/panier.dart';
import 'package:kaomini/widgets/drawer_menu.dart';
import 'package:kaomini/widgets/images.dart';
class PromoArticle extends StatefulWidget {
const PromoArticle({Key? key}) : super(key: key);
_PromoArticleState createState() => _PromoArticleState();
}
class _PromoArticleState extends State<PromoArticle> {
List userdata = [];
int _count = 20;
Future<void> getrecord() async {
var uri = Uri.parse(
My api;
try {
var response = await http.get(
uri,
);
setState(() {
userdata = jsonDecode(response.body);
});
} catch (e) {
print(e);
}
}
void increment(){
setState((){
_count = _count + 10;
});
}
#override
void initState() {
getrecord();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
iconTheme: const IconThemeData(color: Colors.black, size: 33.0),
backgroundColor: Colors.white,
shadowColor: Colors.white,
elevation: 0,
actions: [
Container(
padding: const EdgeInsets.only(right: 19.0),
child: Badge(
badgeColor: Colors.amberAccent,
badgeContent: Text("${Panier.art.length}"),
animationType: BadgeAnimationType.fade,
child: IconButton(onPressed: () => Navigator.push(context, MaterialPageRoute(
builder: (context) => Panier(products: <Product> [
//Product(nom: widget.mail, mail: widget.mail)
],)
)
),
icon: const Icon(Icons.shopping_cart_outlined))),
)
],
bottom: PreferredSize(
child: Container(
alignment: Alignment.bottomLeft,
margin: const EdgeInsets.only(left: 50.0),
child: const Text("Produits en promo",
style: TextStyle(
fontSize: 19.0,
fontWeight: FontWeight.w500,
color: Colors.blue
),
),
),
preferredSize: const Size.fromHeight(20.0),
),
),
body: SingleChildScrollView(
child: Column(
children: [
const SizedBox(height: 20.0,),
GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemCount: userdata == null ? 0 : _count,
itemBuilder: (context, index) {
debugPrint(userdata[index]['photo'].toString());
return userdata == null ? const Center(child: Text('Aucune donnees !'),)
: GestureDetector(
onTap: () => Navigator.push(context, MaterialPageRoute(
builder: (_) => DetailArticle(
id: userdata[index]['id'],
titre: userdata[index]['title'],
description: userdata[index]['description'],
prix: userdata[index]['realPrice'],
image: userdata[index]['pictures'],
prixPromo: userdata[index]["discountPrice"],
//.toString() == null ?
//"https://www.kaomini.ne/uploads/images/logo.png" :
//userdata[index]['photo'],
)
)
),
child: Card(
margin: const EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
//Image.network(userdata[index]['photo'].toString()),
Expanded(
flex: 2,
child: userdata[index]["pictures"] == null ? MyAssetImage.logo1 :
Image.network("https://kaomini.ne/uploads/productPictures/"+userdata[index]["pictures"]),//MyAssetImage.img2
),
Expanded(
child: ListTile(
enabled: false,
title: Row(
children: [
Expanded(
flex: 2,
child: Text(userdata[index]["discountPrice"]+' FCFA',
style: const TextStyle(
color: Colors.blue,
fontWeight: FontWeight.w500,
fontSize: 17.0
),
textAlign: TextAlign.center,
),
),
Expanded(
child: Text(userdata[index]["realPrice"],
style: const TextStyle(
color: Colors.grey,
decoration: TextDecoration.lineThrough,
fontWeight: FontWeight.w300,
fontSize: 15.0
),
textAlign: TextAlign.center,
),
),
],
),
subtitle: Text(userdata[index]["title"],
style: const TextStyle(
fontWeight: FontWeight.w300,
fontSize: 15.0
),
textAlign: TextAlign.center,
),
),
),
],
),
),
);
},
),
ElevatedButton(onPressed: increment,
style: ElevatedButton.styleFrom(
minimumSize: const Size(400, 50),
primary: Colors.blue[100],
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0)),)
),
child: const Text("Voir plus", style: TextStyle(color: Colors.white, fontSize: 16),)
),
],
),
),
endDrawer: const MyMenu(),
);
}
} ```
Change
itemCount: userdata == null ? 0 : _count,
to
itemCount: userdata.isEmpty ? 0 : _count,
or
itemCount: userdata.length,

How to Fix List Items are automatically changing their positing in flutter?

I am calling API data inside Listview. builder in flutter but the error I am facing is the items are changing their positions automatically.
For Example, When I load this class for the First Time the arrangement of List items is the same as required but after 30-40 seconds the List items arrangement automatically starts changing, and data showing itself randomly.
I am looking for someone who can help me to fix this issue?
For this purpose here is myClass Code.
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart'as HTTP;
import 'package:worldcup/utils/colors.dart';
class SeriesSchedulePage extends StatefulWidget {
#override
_SeriesSchedulePageState createState() => _SeriesSchedulePageState();
}
class _SeriesSchedulePageState extends State<SeriesSchedulePage> {
List<dynamic> matches = [];
var match;
getSchedule() async {
http.Response response = await http
.get(Uri.parse("https://api.cricket.com.au/matches/2780"));
final Map parseData = await json.decode(response.body.toString());
matches = parseData['matchList']["matches"];
setState(() {
match = matches;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.primaryWhite,
appBar: AppBar(
backgroundColor: AppColors.yellow,
elevation: 0,
centerTitle: true,
leading: IconButton(
onPressed: () {
Navigator.pop(context,true);
},
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
),
title: Text(
'Schedule',
textScaleFactor: 0.9,
style: GoogleFonts.openSans(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 17),
),
),
body: Container(
child: FutureBuilder(
future: getSchedule(),
builder: (context, snapshot) {
if (match == null) {
return Center(
child: CupertinoActivityIndicator(
animating: true, radius: 15));
} else
return ListView.builder(
itemCount: matches.length,
shrinkWrap: true,
reverse: false,
itemBuilder: (context, index) {
if (matches[index]["status"] =="UPCOMING") {
return Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(7),
),
child: Container(
width: double.infinity,
child: Padding(
padding: EdgeInsets.only(left: 15, top: 7, bottom: 7, right: 15),
child: Row(
children: [
SizedBox(width: 20,),
Expanded(
flex: 2,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
matches[index]['name'].toString(),
textScaleFactor: 0.9,
style: GoogleFonts.openSans(
fontWeight: FontWeight.w700, fontSize: 15),
),
SizedBox(height: 10,),
Text(
matches[index]["homeTeam"]['name'].toString(),
textScaleFactor: 0.9,
style: GoogleFonts.openSans(
fontWeight: FontWeight.w700, fontSize: 15),
),
SizedBox(height: 10,),
Text(
matches[index]["awayTeam"]['name'].toString(),
textScaleFactor: 0.9,
style: GoogleFonts.openSans(
fontWeight: FontWeight.w500, fontSize: 13),
),
],
),
],
),
),
],
),
),
)
);
} else {
return Center(
child: Text("No Upcoming Match in this series"),
);
}
}
);
},
),
)
);
}
}
The issue is because getSchedule() has a setState inside it. When the build method is called, getSchedule() will trigger, and since it is calling setState , the build method is being called again, causing your widgets to continuously rebuild in an infinite loop.
What you need to do is prevent such a loop from happening. I see that you are using FutureBuilder too, that is a solution but your implementation is incorrect.
What you should do is this:
Future<List<dynamic>> getSchedule() async {
http.Response response =
await http.get(Uri.parse("https://api.cricket.com.au/matches/2780"));
final Map parseData = await json.decode(response.body.toString());
var matches = parseData['matchList']["matches"];
return matches;
}
This function returns a Future<List<dynamic>> which your future builder can use to handle the builds. For info on future builder here https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html.
Since you FutureBuilder will react to what is provided by getSchedule() when the future is complete, you do not need to use setState to rebuild.
I have modified your SeriesShedualPage here is the full code:
class SeriesSchedulePage extends StatefulWidget {
#override
_SeriesSchedulePageState createState() => _SeriesSchedulePageState();
}
class _SeriesSchedulePageState extends State<SeriesSchedulePage> {
Future<List<dynamic>> getSchedule() async {
http.Response response =
await http.get(Uri.parse("https://api.cricket.com.au/matches/2780"));
final Map parseData = await json.decode(response.body.toString());
var matches = parseData['matchList']["matches"];
return matches;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: FutureBuilder<List<dynamic>>(
future: getSchedule(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<dynamic> matches = snapshot.data!;
return ListView.builder(
itemCount: matches.length,
shrinkWrap: true,
reverse: false,
itemBuilder: (context, index) {
if (matches[index]["status"] == "UPCOMING") {
return Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(7),
),
child: Container(
width: double.infinity,
child: Padding(
padding: EdgeInsets.only(
left: 15, top: 7, bottom: 7, right: 15),
child: Row(
children: [
SizedBox(
width: 20,
),
Expanded(
flex: 2,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
matches[index]['name'].toString(),
textScaleFactor: 0.9,
),
SizedBox(
height: 10,
),
Text(
matches[index]["homeTeam"]['name']
.toString(),
textScaleFactor: 0.9,
),
SizedBox(
height: 10,
),
Text(
matches[index]["awayTeam"]['name']
.toString(),
textScaleFactor: 0.9,
),
],
),
],
),
),
],
),
),
));
} else {
return Center(
child: Text("No Upcoming Match in this series"),
);
}
});
}
return Center(
child: CupertinoActivityIndicator(animating: true, radius: 15));
},
),
));
}
}

How to fetch specific data from API into flutter app

I am a beginner in flutter.
I have created two ListView Builder where one ListView.builder is inside another builder as given below.
I have a list of categories which is inside one listview.builder and other are the list of products which also listview.builder Wrapped inside the above listview build>
So now i need to display the only items belonging to the 1st listview builder which means If I have a categories named soup (1st ListView.builder) Now i need to display only the products that belongs to soup categories from 2nd Listview.Builder but all the products are listed inside all the categories list. So, Please help me to find solution any help would be appriciated.Thank you in advance.
Below are the codes.
//lib/routes/menu_description.dart(File name)
import 'package:flutter/material.dart';
import '../api_service.dart';
import 'package:html/parser.dart';
import 'package:percent_indicator/percent_indicator.dart';
class MenuDescription extends StatefulWidget {
MenuDescription({Key key}) : super(key: key);
#override
_MenuDescriptionState createState() => _MenuDescriptionState();
}
int itemspressed;
class _MenuDescriptionState extends State<MenuDescription> {
#override
Widget build(BuildContext context) {
return Container(
// color: Colors.grey[200],
child: FutureBuilder(
future: fetchWpPosts(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.separated(
separatorBuilder: (context, index) => Divider(
height: 20.0,
color: Colors.black,
),
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
Map wpcategoriespost = snapshot.data[index];
return Container(
color: Colors.grey[200],
child: InkWell(
splashColor: Colors.grey[800],
onTap: () {
setState(() {
itemspressed = index;
});
},
child: Padding(
padding: const EdgeInsets.only(
left: 5, right: 5, bottom: 5, top: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Text(
"${wpcategoriespost['name']}",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.lightGreen[900],
),
),
),
Center(
child: Text(
parse(("${wpcategoriespost['description']}")
.toString())
.documentElement
.text,
style:
TextStyle(fontSize: 14, color: Colors.black),
),
),
Container(
padding: EdgeInsets.only(top: 20.0),
child: Categories(),)
],
),
),
),
);
},
);
}
return new CircularPercentIndicator(
radius: 120.0,
lineWidth: 13.0,
animation: true,
percent: 1.0,
progressColor: Colors.orange,
center: new Text(
"100.0%",
style:
new TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
));
},
),
);
}
}
class Categories extends StatefulWidget {
#override
_CategoriesState createState() => _CategoriesState();
}
class _CategoriesState extends State<Categories> {
#override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: fetchWpPosts(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
Map wppost = snapshot.data[index];
return Card(
margin: const EdgeInsets.only(
left: 15,
right: 15,
bottom: 15,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
elevation: 3,
child: InkWell(
splashColor: Colors.grey[300],
onTap: () {
setState(() {
itemspressed = index;
});
},
child: Padding(
padding: const EdgeInsets.only(
left: 12, right: 5, bottom: 12, top: 5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"${wppost['name']}",
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.lightGreen[900]),
),
Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
border: Border.all(color: Colors.grey[350]),
color: itemspressed == index
? Colors.grey[350]
: null,
),
child: IconButton(
iconSize: 22,
icon: Icon(
Icons.add,
color: Colors.blueAccent[400],
),
onPressed: () {
setState(() {});
print('Add to cart');
},
),
),
],
),
Text(
parse(("${wppost['description']}").toString())
.documentElement
.text,
style: TextStyle(fontSize: 14, color: Colors.black),
),
Text(
parse(("${wppost['price']} €").toString())
.documentElement
.text,
style: TextStyle(
fontSize: 15,
color: Colors.amber[700],
fontWeight: FontWeight.bold),
),
],
),
),
),
) ;
},
);
}
return new CircularPercentIndicator(
radius: 120.0,
lineWidth: 13.0,
animation: true,
percent: 1.0,
progressColor: Colors.orange,
center: new Text(
"100.0%",
style:
new TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
));
},
),
);
}
}
//lib/api_service.dart
import 'package:http/http.dart' as http;
import 'dart:convert';
Future<List> fetchWpPosts() async{
final response = await http.get('https://word.tkco.in/wp-json/wc/v3/products?consumer_key=ck_94114a31e4576e61a9292f961489e7701029753e&consumer_secret=cs_dd4dc6e7945d8dcd14d888bc1d0ea0806b116dfb');
var convertDatatoJson = jsonDecode(response.body);
if (response.statusCode == 200) {
}
return convertDatatoJson;
}

listview.separated flutter showing blank page even it has data

hi I am new to flutter and dart, i have this issue that the page is showing no data , even though there is data inside listView.seperator , when i check with dubugger , i get data in snapshot.data[index].finishedProductId Or finishedProductName or categoryShortName, but debugger finish it shows blank page, even deleting all i just but Text , still it shows blank page i am giving the code, plz help me. i am giving my code as below thanks in advance. I have marked my website link with start , just for security. Sorry for this.
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
class DetailsPage extends StatefulWidget {
final String itemCode;
DetailsPage({Key key, this.itemCode}) : super(key: key);
#override
_DetailsPageState createState() => _DetailsPageState();
}
class _DetailsPageState extends State<DetailsPage> {
// ignore: missing_return
Future<List<ItemDetails>> _getItemDetails() async {
final response = await http.get(
'https://www.****.com/appfiles/getprodcontent.php?getContent=' +
this.widget.itemCode );
var jsonData = jsonDecode(response.body);
print(jsonData);
List<ItemDetails> itemDet = [];
for (var it in jsonData) {
ItemDetails iDet = ItemDetails(
it['imgPath'],
it['finishedProductId'],
it["finishedProductName"],
it["categoryShortName"],
);
itemDet.add(iDet);
}
print(itemDet.length);
return itemDet;
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueGrey[200],
appBar: AppBar(
title: Text("Product Details of " + this.widget.itemCode),
),
body: Container(
child: FutureBuilder(
initialData: [],
future: _getItemDetails(),
// ignore: missing_return
builder: (BuildContext context, AsyncSnapshot snapshot) {
//if(snapshot.connectionState == ConnectionState.done){
//if (snapshot.data == null) {
// return Container(
// child: Center(
// child: Text('Loading...'),
/// ));
// } else {
return Column(
children: <Widget> [
SizedBox(
height:200,
child: ListView.seperated(
padding: const EdgeInsets.all(8),
itemCount: snapshot.data.length,
// ignore: missing_return
itemBuilder: (BuildContext context, int index) {
Container (
child:
Center(child: Text("finished product id") ,),
);
Container(
height: 50,
color: Colors.amber[200],
child: Center(
child: CircleAvatar(
radius: 50.0,
backgroundImage: NetworkImage(
"https://www.shardaudyogmandir.com/assets/thumbs/javaschatni.png")
!= null ?NetworkImage("https://www.****.com/assets/thumbs/***.png") : Container() ,
),
),
);
Container(
height: 50,
color: Colors.amber[200],
child: Center(
child: Text(snapshot.data[index].finishedProductId != null ? snapshot.data[index].finishedProductId: "",
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold)),
),
);
Container(
height: 50,
color: Colors.amber[200],
child: Center(
child: Text(snapshot.data[index].finishedProductName != null ? snapshot.data[index].finishedProductName: "",
style: TextStyle(color: Colors.black)),
),
);
Container(
height: 50,
color: Colors.amber[200],
child: Center(
child: Text(snapshot.data[index].categoryShortName != null ? snapshot.data[index].categoryShortName : "",
style: TextStyle(color: Colors.black)),
),
);
Container(
height: 50,
color: Colors.amber[200],
child: Center(
child: RaisedButton(
color: Colors.green[700],
onPressed: () {
//print("press view details");
},
child: const Text('Add To Cart',
style: TextStyle(
fontSize: 20,
color: Colors.white)),
),
),
);
},
//separatorBuilder: (BuildContext context, int index) =>
//const Divider(),
),
)
],
);
//}
//}
}
)
),
);
}
}
class ItemDetails {
final String finishedProductId;
final String finishedProductName;
final String categoryShortName;
//final String rawMaterialName;
final String imgPath;
ItemDetails(this.imgPath, this.finishedProductId, this.finishedProductName,
this.categoryShortName);
}
You need to add return inside Item Builder method like this :
itemBuilder: (BuildContext context, int index) {
return Column(
children: [
Container(
height: 50,
color: Colors.amber[200],
child: Center(
child: CircleAvatar(
radius: 50.0,
backgroundImage: NetworkImage(
"https://www.******.com/assets/thumbs/****.png")
!= null ?NetworkImage("https://www.shardaudyogmandir.com/assets/thumbs/javaschatni.png") : Container() ,
),
),
),
Container (
child:
Center(child: Text("finished product id") ,),
),
Container(
height: 50,
color: Colors.amber[200],
child: Center(
child: Text(snapshot.data[index].finishedProductId != null ? snapshot.data[index].finishedProductId: "",
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold)),
),
),
Container(
height: 50,
color: Colors.amber[200],
child: Center(
child: Text(snapshot.data[index].finishedProductName != null ? snapshot.data[index].finishedProductName: "",
style: TextStyle(color: Colors.black)),
),
),
Container(
height: 50,
color: Colors.amber[200],
child: Center(
child: Text(snapshot.data[index].categoryShortName != null ? snapshot.data[index].categoryShortName : "",
style: TextStyle(color: Colors.black)),
),
),
Container(
height: 50,
color: Colors.amber[200],
child: Center(
child: RaisedButton(
color: Colors.green[700],
onPressed: () {
//print("press view details"),
},
child: const Text('Add To Cart',
style: TextStyle(
fontSize: 20,
color: Colors.white)),
),
),
),
],
);
},
And wrap it inside column. I don't know how the UI will be look like but that's the problem from your code. For further information head on Flutter.Dev

How to add item in a listview from one class to another in Flutter?

I am working on a project in which i have a class which has a row that has two children. Child one contains a TabView with a child class TabViewChild in which i am generating a gridview. On the other hand child two contains a listView. So the problem is, when i click on the gridview item i am passing that item's value to a static list and passing that list to a listview of other class. But i have no idea how to change the state of that class on item clicked or how can i achieve this task in a better way as i am new to Flutter. I want that when a person click on any gridview's item that item appears in the listview simultaneously.
class ItemMenus {
int id;
String code;
String name;
String salePrice;
String photo;
String categoryName;
String percentage;
int quantity;
ItemMenus({this.id, this.code, this.name, this.salePrice, this.photo,
this.categoryName, this.percentage, this.quantity});
ItemMenus.fromJson(Map<String, dynamic> json)
:
id = int.parse(json['id']),
code = json['code'],
name = json['name'],
salePrice = json['sale_price'],
photo = json['photo'],
categoryName = json['category_name'],
percentage = json['percentage'];
#override
String toString() {
return 'ItemMenus{id: $id, code: $code, name: $name, salePrice: $salePrice, photo: $photo, categoryName: $categoryName, percentage: $percentage}';
}
}
import 'package:food_app/model/mdl_item_menus.dart';
class ItemMenuList{
List<ItemMenus> _itmMenuLst = [];
ItemMenuList._();
static final ItemMenuList instanceItmMenuLst = ItemMenuList._();
static ItemMenuList get instance => instanceItmMenuLst;
void addItem(ItemMenus im){
_itmMenuLst.add(im);
}
List<ItemMenus> get list => _itmMenuLst;
#override
String toString() {
return 'ItemMenuList{_itmMenuLst: $_itmMenuLst}';
}
}
import 'package:flutter/material.dart';
import 'package:food_app/database/tables/tbl_categories.dart';
import 'package:food_app/model/list/item_menu_list.dart';
import 'package:food_app/model/mdl_categories.dart';
import 'package:food_app/model/mdl_item_menus.dart';
import 'package:food_app/pos/tab_bar_view.dart';
class EPos extends StatefulWidget{
#override
_EPosState createState() => _EPosState();
}
class _EPosState extends State<EPos> {
final categoryDBHelper = TblCategories.categoriesInstance;
final ItemMenuList instance2 = ItemMenuList.instance;
String _orderType = 'Dine-In', _info = 'Table No. 1', _userName = 'ZiaUddin';
List<Categories> catLst = [];
List<ItemMenus> itmLst = [];
Future getCategories() async {
catLst.clear();
var categories = await categoryDBHelper.getCategories();
categories.forEach((element) {
catLst.add(Categories(
id: element['id'],
categoryName: element['category_name'],
description: element['description'],
userId: element['user_id'],
companyId: element['company_id'],
delStatus: element['del_status']));
});
catLst.forEach((element) {
print(element);
});
return catLst;
}
#override
void initState() {
// TODO: implement initState
super.initState();
// itmLst = instance2.list;
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Column(
children: [
//#region AppBar
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.15,
color: Colors.redAccent,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
margin: EdgeInsets.fromLTRB(8, 10, 0, 0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(20),
color: Colors.red,
),
child: Row(
children: [
Icon(
Icons.arrow_back,
color: Colors.white,
size: 25,
),
Padding(
padding: const EdgeInsets.fromLTRB(4, 8, 10, 8),
child: Text(
_orderType,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
fontFamily: 'Ubuntu',
letterSpacing: 2.0,
),
),
),
],
),
),
Container(
margin: EdgeInsets.fromLTRB(8, 10, 0, 0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10),
color: Colors.red,
),
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 8, 20, 8),
child: Text(
_info,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.amberAccent,
fontFamily: 'Ubuntu',
letterSpacing: 2.0,
),
),
),
),
Container(
margin: EdgeInsets.only(top: 15, right: 5),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(30),
color: Colors.red,
),
child: Row(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(10, 8, 8, 8),
child: Text(
_userName,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.normal,
color: Colors.white,
fontFamily: 'Ubuntu',
letterSpacing: 1.0,
),
),
),
CircleAvatar(
backgroundColor: Colors.red,
radius: MediaQuery.of(context).size.height * 0.041,
child: CircleAvatar(
radius: MediaQuery.of(context).size.height * 0.04,
backgroundImage: AssetImage('assets/user.png'),
),
),
],
),
),
],
),
),
//endregion
Expanded(
child: Row(
children: [
//# region Menu
Flexible(
flex: 1,
child: Container(
decoration: BoxDecoration(
color: Colors.yellowAccent,
shape: BoxShape.rectangle,
),
child: Column(
children: [
Expanded(
child: Container(
color: Colors.white,
child: FutureBuilder(
future: getCategories(),
builder: (context, snapShot) {
if (snapShot.connectionState ==
ConnectionState.none &&
snapShot.hasData == null) {
return Center(
child: CircularProgressIndicator());
}
return MaterialApp(
debugShowCheckedModeBanner: false,
home: DefaultTabController(
length: catLst.length,
child: Scaffold(
backgroundColor: Colors.white,
appBar: PreferredSize(
preferredSize:
Size.fromHeight(kToolbarHeight),
child: Container(
height: MediaQuery.of(context)
.size
.height *
0.1,
child: TabBar(
indicatorColor:
Colors.amberAccent,
isScrollable: true,
tabs: catLst
.map<Widget>((Categories c) {
return Tab(
icon: Icon(
Icons.style,
color: Colors.amberAccent,
size: 15,
),
child: Text(
c.categoryName
.toUpperCase(),
style: TextStyle(
color: Colors.black,
fontWeight:
FontWeight.w400,
),
),
);
}).toList(),
),
),
),
body: TabBarView(
children: catLst.map((Categories c) {
return TabBarViewChild(categoryName:c.categoryName,
callback: (){
setState(() {
instance2.addItem(ItemMenus(name: c.categoryName));
itmLst = instance2.list;
print('I am Callback');
});
},);
}).toList(),
),
),
),
);
}),
),
),
],
),
),
),
//endregion
//# region OrderList
Flexible(
flex: 1,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
),
child: ListView.builder(
itemCount: itmLst.length,
itemBuilder: (context, index){
return ListTile(
title: Text(itmLst[index].name),
);
},
),
),
),
//endregion
],
),
),
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:food_app/database/tables/tbl_item_menus.dart';
import 'package:food_app/model/list/item_menu_list.dart';
import 'package:food_app/model/mdl_item_menus.dart';
import 'package:food_app/pos/new_sale.dart';
class TabBarViewChild extends StatefulWidget {
String categoryName;
VoidCallback callback;
TabBarViewChild({Key key,#required this.categoryName, this.callback}) : super(key:key);
#override
_TabBarViewChildState createState() => _TabBarViewChildState();
}
class _TabBarViewChildState extends State<TabBarViewChild> {
final ItemMenuList instance1 = ItemMenuList.instance;
List<ItemMenus> itmLst = [];
final itemMenus = TblItemMenus.itemMenusInstance;
Future getSpecificItemMenus() async{
var items = await itemMenus.getSpecificItemMenus(widget.categoryName);
itmLst.clear();
items.forEach((e) {
itmLst.add(ItemMenus(id: e['id'], categoryName: e['category_name'], code: e['code'],
name: e['name'], percentage: e['percentage'], photo: e['photo'], quantity: e['quantity'],
salePrice: e['sale_price']));
});
for (var value in itmLst) {
print(value);
}
return itmLst;
}
#override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
color: Colors.white,
child: FutureBuilder(
future: getSpecificItemMenus(),
builder: (context, snapShot) {
if (snapShot.connectionState == ConnectionState.none
&& snapShot.hasData == null) {
return Center(child: CircularProgressIndicator());
}
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
scrollDirection: Axis.vertical,
itemCount: itmLst.length,
itemBuilder: (context, index){
return Padding(
padding: const EdgeInsets.all(5.0),
child: InkWell(
child: Card(
elevation: 4,
color: Colors.amberAccent,
child: Center(
child: Text(
itmLst[index].name.toUpperCase(),
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.red,
fontSize: 13,
fontWeight: FontWeight.w700,
fontFamily: 'Ubuntu',
letterSpacing: 1.0,
),
),
),
),
onTap: (){
// Provider.of<ProItemMenus>(context, listen: false).addNewItemInList(ItemMenus(name: itmLst[index].name.toUpperCase()));
instance1.addItem(ItemMenus(categoryName: itmLst[index].name.toUpperCase()));
print(itmLst[index].name.toUpperCase());
},
),
);
}
);
}
),
);
}
}
So the problem now, there are two stateful widgets.
And as we are going to share the data or the state between them, basically we need to have more one stateful Widget which will the parent of them.
This term of is this problem known as State Management.
Currently there are many reknown State Management , such as Provider and Bloc. Reference.
But personally, I recommend to use Provider, which has simple Syntaxes and Concept.