Fill in the template. Issues that do not respect the model will be closed.
Hello Jonny Borges,
First of all I'd like to thank you for developing this superior package, and i wish you good health.
Describe the bug
This is not a bug but please hear me out. I started to learn flutter recently, and i decided to learn Getx along with it. in the course videos in the state management section, every time the tutor uses "provider" i use "GetX" instead.
Right now i'm facing a problem with get producing a widget from list to form a Gridview.builder.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Build a Gridview of widgets from a List.
Screenshots

Flutter Version:
1.17.5
Get Version:
3.4.0
Describe on which device you found the bug:
OnePlus6T- Android
Minimal reproduce code
-------products_grid.dart--------
class ProductsGrid extends StatelessWidget {
@override
Widget build(BuildContext context) {
final Products loadedProducts = Get.put(Products());
return GetBuilder<Products>(
builder: (_) => GridView.builder(
padding: const EdgeInsets.all(10.0),
itemCount: loadedProducts.items.length,
itemBuilder: (ctx, index) => Builder(
builder: (c) => ProductItem(
// id: loadedProducts.items[index].id,
// title: loadedProducts.items[index].title,
// imageUrl: loadedProducts.items[index].imageUrl,
),
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
),
);
}
}
------- products.dart ----------
class Products extends GetxController {
List<Product> _items = [
Product(
id: 'p1',
title: 'Red Shirt',
description: 'A red shirt - it is pretty red!',
price: 29.99,
imageUrl:
'https://cdn.pixabay.com/photo/2016/10/02/22/17/red-t-shirt-1710578_1280.jpg',
),
Product(
id: 'p2',
title: 'Trousers',
description: 'A nice pair of trousers.',
price: 59.99,
imageUrl:
'https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Trousers%2C_dress_%28AM_1960.022-8%29.jpg/512px-Trousers%2C_dress_%28AM_1960.022-8%29.jpg',
),
];
List<Product> get items => [..._items];
Product findById(String id) {
return _items.firstWhere((prod) => prod.id == id);
}
void addProduct() {
// _items.add(value);
update();
}
}
-------- product.dart--------------
class Product extends GetxController {
final String id;
final String title;
final String description;
final double price;
final String imageUrl;
bool isFavorite;
Product({
@required this.id,
@required this.title,
@required this.description,
@required this.price,
@required this.imageUrl,
this.isFavorite = false,
});
}
------product_item.dart -----------
class ProductItem extends StatelessWidget {
// final String id;
// final String title;
// final String imageUrl;
//
// ProductItem({this.id, this.title, this.imageUrl});
@override
Widget build(BuildContext context) {
final Product loadedProducts = Get.put(Product());
return ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: GridTile(
child: GestureDetector(
onTap: () {
Navigator.of(context).pushNamed(ProductDetailScreen.routeName,
arguments: loadedProducts.id);
},
child: Image.network(
loadedProducts.imageUrl,
fit: BoxFit.cover,
),
),
footer: GridTileBar(
backgroundColor: Colors.black87,
leading: IconButton(
icon: Icon(Icons.favorite),
color: Theme.of(context).accentColor,
onPressed: () {}),
trailing: IconButton(
icon: Icon(Icons.shopping_cart),
color: Theme.of(context).accentColor,
onPressed: () {}),
title: GetBuilder<Product>(
builder: (_) => Text(
loadedProducts.title,
textAlign: TextAlign.center,
),
),
),
),
);
}
}
hi, I think the slack channel is a good place to put this kind of questions. See the readme to the group for channel.
Having said that I am also new to flutter and GetX but i think this might help you: (i guess the onAdd/delete method will be the GetX dynamic benefits, for now it is just create a list in the oninit) (note the images are quite big so take some second to load i had some issue with your trouser image url)
the controller
import 'package:get/get.dart';
import 'package:myapp/models/product.dart';
class Products extends GetxController {
List<Product> items = [];
Products() {}
@override
onInit() {
items = [
Product(
id: 'p1',
title: 'Red Shirt',
description: 'A red shirt - it is pretty red!',
price: 29.99,
imageUrl:
'https://www.carlogos.org/car-logos/bmw-logo-1997-1200x1200-show.png',
),
Product(
id: 'p2',
title: 'Trousers',
description: 'A nice pair of trousers.',
price: 59.99,
imageUrl: 'https://www.carlogos.org/logo/Saab-logo-2002-640x550.jpg',
),
];
update();
super.onInit();
}
List get myitems => [...items];
Product findById(String id) {
return items.firstWhere((prod) => prod.id == id);
}
void addProduct() {
// _items.add(value);
update();
}
}
Widget myWidget() {
return Container(
child: GetBuilder<Products>(
init: Products(),
builder: (data) => GridView.builder(
padding: const EdgeInsets.all(10.0),
itemCount: data.items.length,
itemBuilder: (ctx, index) {
var pitem = data.items[index];
return ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: GridTile(
child: GestureDetector(
onTap: () {},
child: Image.network(
pitem.imageUrl,
fit: BoxFit.cover,
),
),
footer: GridTileBar(
backgroundColor: Colors.black87,
leading: IconButton(icon: Icon(Icons.favorite), onPressed: () {}),
trailing:
IconButton(icon: Icon(Icons.shopping_cart), onPressed: () {}),
title: Text(
pitem.title,
textAlign: TextAlign.center,
),
),
),
);
},
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
),
));
}
and myWidget can be the in the body
body: myWidget(),
Hello!
Let me just say, @lundin got it right, his code looks like is perfectly functional.
What i am gonna do is tell you the few wrong things in your code.
Lets begin
The correct way of initialize a controller is inside the GetBuilder, this way:
GetBuilder<Products>(
init: Products(),
builder: (products) => GridView.builder(
// your code
),
);
This way there is less chance of having problems.
Get.put<Products>(Products()) is the same as init: Products(), but as i said is less prone to beginner user errorsIf you need to use the same controller in other place of the code, you can use var products = Get.find<Products>() to get that same instance that you already used it.
This one is fine, i didn't noticed anything wrong
this one is fine
you should pass from ProductsGrid to ProductItem at least the index, so you can know where to get information from the array
Why are you using Get.put() to save a model class? You will use multiple instances of this same class, each one with different values. And worst, you initialized a empty product instance! that's why is giving this error, there is no data
the correct is:
class ProductItem extends StatelessWidget {
final index;
ProductItem({this.index});
@override
Widget build(BuildContext context) {
return GetBuilder<Products>(
builder (products) => GridTile(
// now that you have the index, you can make like that
// products.items[index].imageUrl
)
);
}
}
i did not write all the code because this response is getting big
that's it, i hope it helps you understanding better this package
Thank you both very much for the help, next time I'll try slack channel before posting here.
i have yet much to learn.
Again thank you.
Most helpful comment
Hello!
Let me just say, @lundin got it right, his code looks like is perfectly functional.
What i am gonna do is tell you the few wrong things in your code.
Lets begin
ProductsGrid:
The correct way of initialize a controller is inside the GetBuilder, this way:
This way there is less chance of having problems.
Note: Only initialize your controller once! Don't forget that
Note虏:
Get.put<Products>(Products())is the same asinit: Products(), but as i said is less prone to beginner user errorsIf you need to use the same controller in other place of the code, you can use
var products = Get.find<Products>()to get that same instance that you already used it.Products:
This one is fine, i didn't noticed anything wrong
Product:
this one is fine
ProductItem
you should pass from ProductsGrid to ProductItem at least the index, so you can know where to get information from the array
Why are you using Get.put() to save a model class? You will use multiple instances of this same class, each one with different values. And worst, you initialized a empty product instance! that's why is giving this error, there is no data
the correct is:
i did not write all the code because this response is getting big
that's it, i hope it helps you understanding better this package