Flutter array looping list - flutter

I am making my own flutter application, but I ran into a problem. I am creating a Breakfast class
class Breakfast {
String foodTitle;
String foodCalories;
Breakfast({this.foodTitle, this.foodCalories});
}
From this class i create an array with objects of that class
class BreakfastFood {
List<Breakfast> _breakfastFoodData = [
Breakfast(
foodTitle: "Bread",
foodCalories: "100",
),
Breakfast(
foodTitle: "Soup",
foodCalories: "50",
),
];
int _foodTitle = 0;
int _foodCalories = 0;
String getFoodTitle() {
return _breakfastFoodData[_foodTitle].foodTitle;
}
String getFoodCalories() {
return _breakfastFoodData[_foodCalories].foodCalories;
}
}
I have created a component which gets the foodtitle and foodCalories and puts them in a widget.
Now i want to make a function that loops through the objects of the _breakfastfoodData and shows them. But I don't know how to loop through the list and show all the objects seperate from eachother.

_breakfastFoodData in your code is private property (because it begins _), you should change to breakfastFoodData.
You use ListView.builder to build your list:
List<Breakfast> datas= new BreakfastFood().breakfastFoodData;
return ListView.builder(
itemCount: datas.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('${datas[index].foodTitle}'),
);
},
);

You just have to define your class as here:
class BreakfastFood {
List<Breakfast> _items = [
Breakfast(
foodTitle: "Bread",
foodCalories: "100",
),
Breakfast(
foodTitle: "Soup",
foodCalories: "50",
),
];
List<Breakfast> get items => [..._items];
}
and Then call it threw list view for display all items:
BreakfastFood foodData = BreakfastFood();
ListView.builder(
itemCount: foodData.items.length,
itemBuilder: (ctx, index) {
return ListTile(
title: Text('${foodData.items[index].foodTitle}'),
subTitle: Text('${foodData.items[index].foodCalories}'),
);
}
)

Related

How to show category list from firestore in flutter?

I have a product named collection,
In that product collection I have saved products with their name and category. Now I need to create a tab bar with all the category list inside products. The problem is there are multiple products with same category. And I want that category to be shown once. How to achieve this?
This is my code:
StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance.collection('products') .where("category").snapshots(),
builder: (_, snapshot) {
if (snapshot.hasError) return Text('Error = ${snapshot.error}');
if (snapshot.hasData) {
final docs = snapshot.data!.docs;
return ListView.builder(
itemCount: docs.length,
itemBuilder: (_, i) {
final data = docs[i].data();
Set s = {};
s.add( data["category"]);
return ListTile(
title: Text(s.elementAt(0).toString()),
);
},
);
}
return Center(child: CircularProgressIndicator());
},
)
You must provide ur code ,
guessing this code will help u to implement ur code....
here I have taken Movie instead of product..U may correct it based on ur requirement...
class Movie {
String name;
String category;
String language;
int rating;
Movie(
{required this.name,
required this.category,
required this.language,
required this.rating});
}
void main() {
List<Movie> movielist = [
Movie(name: 'Golmaal', category: 'Comedy', language: 'Hindi', rating: 5),
Movie(name: 'Naseeb', category: 'Classic', language: 'Hindi', rating: 5),
Movie(name: 'Hera Phery', category: 'Comedy', language: 'Hindi', rating: 5)
];
final categories = movielist.map((e) => e.category).toSet();//this will generate unique category list..
print(categories);
// now use this categories to ur design with listview or any list widgets
}

Getx How to refresh list by using Obx

I'm working with ReorderableSliverList but I have no idea how to observe the list based on my data dynamically.
Screen 1
ReorderableSliverList(
delegate: ReorderableSliverChildBuilderDelegate(
(BuildContext context, int index) {
final data = controller.products[index];
return ItemView(data);
},
childCount: controller.products.length),
onReorder: _onReorder,
)
At screen2 will have a add button to call controller insert new data into list
controller
var products = List<Product>.empty().obs;
void add(String name) {
if (name != '') {
final date = DateTime.now().toIso8601String();
ProductProvider().postProduct(name, date).then((response) {
final data = Product(
id: response["name"],
name: name,
createdAt: date,
);
products.add(data);
Get.back();
});
} else {
dialogError("Semua input harus terisi");
}
}
The code above need to click Hot reload in order to show data in screen 1 if data has changed from screen 2.
I'm trying to use Obx to make it refresh automatically but the result it still the same.
Code
ReorderableSliverList(
delegate: ReorderableSliverChildBuilderDelegate(
(BuildContext context, int index) {
final data = controller.products[index];
return Obx(
() => controller.products.isEmpty
? Center(
child: Text("BELUM ADA DATA"),
)
: ItemView(data)
);
}, childCount: controller.products.length),
onReorder: _onReorder,
)
You need to wrap the whole ReorderableSliverList with Obx like this:
Obx(()=>ReorderableSliverList(
...
...
));

Dynamically add dimensions to boolean array

I'm using flutter to develop an e-commerce app.
I'm working on the navDrawer for it and I could use some help with the categories.
I have categories that can have subcategories and the subcategories can also have their own subcategories.
Basically, the data set is an array of unknown dimensions.
I need to make a boolean map for my categories and subcategories so that I can keep track of which ones are open in order to show the subcategories.
Here's an example of the dataset:
{
"id":"41490",
"name":"Electrical Equipment",
"subCategories":[
{
"id":"41492",
"name":"Breakers",
"subCategories":[
{
"id":"167542",
"name":"1 Pole",
"subCategories":[
{
"id":"167577",
"name":"15 Amp",
"subCategories":null
},
{
"id":"167585",
"name":"20 Amp",
"subCategories":null
},
{
"id":"167600",
"name":"30 Amp",
"subCategories":null
},
{
"id":"167606",
"name":"40 Amp",
"subCategories":null
}
]
},
I think recursion is the optimal way to process this dataset but the problem I'm having is that I can't figure out how to have dynamic dimensions for an array in Dart.
I already figured out how to generate my listTiles from the dataset but I can't figure out the boolean map.
Is this even possible or should I look into a different approach?
Here's my code for generating the listTiles from the dataset:
void setCategories(List categories){
_categories = categories;
int catCount = categories.length;
_categoryList = new ListView.builder(
//shrinkWrap: true,
//physics: ClampingScrollPhysics(),
padding:EdgeInsets.all(0.0),
itemCount: catCount,
itemBuilder: (BuildContext context, int index) => buildCategories(context, index),
);
}
Widget buildCategories(BuildContext context, int index){
if(_categories[index]['subCategories']!=null){
//TODO: call buildSubCategories with depth of 1 parameter
return Container(
height: 30.0,
child: ListTile(
title: Row(
children:[
Text(" "+_categories[index]['name']),
Transform.scale(
scale: 0.75,
child:
Icon(Icons.arrow_back)
)
]
),
onTap: () {
//TODO: implement boolean map here
}
),
padding: EdgeInsets.all(0.0),
margin: EdgeInsets.all(0.0)
);
} else {
return Container(
height: 30.0,
child: ListTile(
title: Text(" "+_categories[index]['name']),
onTap: () {
}
),
padding: EdgeInsets.all(0.0),
margin: EdgeInsets.all(0.0)
);
}
}
Widget buildSubCategories(var parent, int depth){
List subCategoryList = parent['subCategories'];
int subCategoryCount = subCategoryList.length;
if(parent['subCategories']!=null){
//for each subCategory
//if subCategory has subCategories
//recurse subCategory with depth
buildSubCategories(parent['subCategories'], depth++);
//TODO: implement boolean map here
} else {
//
}
}
void generateCategoryBooleanMap(){
//TODO: generate boolean map here
//TODO: boolean map needs to have a undetermined amount of depth levels
}
Any insight is appreciated even if it means I have to use a different paradigm.
Example of using a Set to keep track of which id is open:
void main() {
final idHandler = IdHandler();
print(idHandler.isIdOpen('MyId')); // false
idHandler.openId('MyId');
print(idHandler.isIdOpen('MyId')); // true
idHandler.closeId('MyId');
print(idHandler.isIdOpen('MyId')); // false
idHandler.openId('MyId');
print(idHandler.isIdOpen('MyId')); // true
idHandler.closeAll();
print(idHandler.isIdOpen('MyId')); // false
}
class IdHandler {
final Set<String> _openIds = {};
void openId(String id) => _openIds.add(id);
void closeId(String id) => _openIds.remove(id);
void closeAll() => _openIds.clear();
bool isIdOpen(String id) => _openIds.contains(id);
}

Change List Tile trailing using provider

The problem is that when a List Tile is tapped the quantity is incremented for all the list tiles.
I have a stateless widget which has this build method :
final ProductsList productsList = ProductsList(context);
return Scaffold(
body: Center(child: productWidget(productsList, args)));
}
This is the ProductWidget
FutureBuilder productWidget(productsList) {
return FutureBuilder(
future: getProducts,
builder: (context, products) {
switch (products.connectionState) {
case ConnectionState.waiting:
return Text('Loading....');
default:
return Scaffold(
body: productsList.build(products.data));
}
},
);
And this is what productsList.build does:
ProductsList(this.context);
Padding getProduct(name) {
int _quantity = Provider.of<Quantity>(context).getQuantity();
return ListTile(
key: UniqueKey(),
onTap: () {
Provider.of<Quantity>(context, listen: false).incrementQuantity();
},
title: Text(name),
trailing: Text("$_quantity"),
),
);
}
ListView build(products) {
List<Widget> _products = new List();
for (var i = 0; i < products.length; i++) {
_products.add(getProduct(products[i].name));
}
return ListView(
children: _products,
);
}
and I am using this changeNotifier :
class Quantity extends ChangeNotifier {
int _quantity = 0;
void incrementQuantity(){
_quantity += 1;
notifyListeners();
}
int getQuantity() {
return _quantity;
}
}
I want to tap a list tile and increment just it's value which is displayed in the trailing, but not of the others.
I am using multi-provider in the main file of the application.
Provider needs to track quantity by product. Your Provider is tracking quantity as a single int so the result you are seeing is correct for your code.
Quantity should be List. You can also set the initial value.
Then
incrementQuantity(int index) {
increment quantity[index] here
}
And
get quantity(int index){
return quantity[index]
}
On a side note, in my opinion, your efforts would benifit greatly by researching using ListTile with Provider.

Flutter Mixed List - How to push every 6 items to grid style with two columns from mixed list?

Hi there please help me how to push item from list to grid, i have implement this https://flutter.dev/docs/cookbook/lists/mixed-list , what i want is how to push every 6 MessageItem to grid with two columns. thanks.
here my sample code:
ListView.builder(
controller: _controller,
itemCount: widget.ditems.length,
itemBuilder: (context, index) {
final item = widget.ditems[index];
if (item is HeadingItem) {
return TabHomeHeaderUi();
} else if (item is HeadlineItem) {
return TabHomeHeadline();
} else if (item is PopularItem) {
return TabHomePopular();
} else if (item is MessageItem) {
return
//here return 6 item
ListTile(
title: Text(item.sender),
subtitle: Text(item.body),
);
}
},
),