I'm working on a shopping app for a school project, and I'm trying to get my product images and details to show up on the various product detail screens. I used some sample images from flutter's Shrine sample app as I followed their tutorial. The problem I'm facing now is an endless Listview scroll that looks like this, and when you keep scrolling, it repeats the image and details endlessly:
What should I do to avoid this? Sorry, I am really new to coding so I am not to sure how to go about fixing this problem...Below I have included a few dart files of my current code which might be helpful. Thank you to anyone who is willing to help, it is very much appreciated!
Product detail screen dart file:
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:MyShoppingApp/provider/CartProvider.dart';
import 'package:MyShoppingApp/db/cart_database.dart';
import 'package:MyShoppingApp/model/cart.dart';
import 'model/products_repository.dart';
import '../model/cart.dart';
class ProductDetailsPage extends StatelessWidget {
static const routeName = '/user-products';
ProductDetailsPage({Key? key}) : super(key: key); //const
DBHelper dbHelper = DBHelper();
@override
Widget build(BuildContext context) {
//get particular productId using the ModalRoute class
final productId = ModalRoute.of(context)!.settings.arguments as String;
print(productId);
//use Provider package to find out ID by accessing method declared in Product()
final loadedProduct = ProductsRepository().findById(productId);
//List<bool> clicked = List.generate(10, (index) => false, growable: true);
final cart = Provider.of<CartProvider>(context);
void saveData(int index) {
dbHelper
.insert(
CartItem(
id: index,
title: loadedProduct.name,
price: loadedProduct.price.toDouble(),
quantity: ValueNotifier(1),
image: loadedProduct.image,
),
)
.then((value) {
cart.addTotalPrice(loadedProduct.price.toDouble());
cart.addCounter();
print('Product Added to cart');
}).onError((error, stackTrace) {
print(error.toString());
});
}
return Scaffold(
backgroundColor: Colors.orange[50],
appBar: AppBar(
backgroundColor: Colors.deepOrange[900],
title: const Text("Product details "),
leading: IconButton(
icon: const Icon(
Icons.arrow_back_ios_outlined,
color: Colors.black,
semanticLabel: 'back to home',
),
onPressed: () {
Navigator.pop(context);
},
),
),
//body:
body: ListView.builder(
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 8.0),
shrinkWrap: true,
itemCount: loadedProduct.length,
itemBuilder: (context, index) {
return Card(
//SingleChildScrollView(
child: Column(
children: <Widget>[
SizedBox(
height: 300,
width: double.infinity,
child: Image.asset(
loadedProduct.image,
fit: BoxFit.cover,
),
),
const SizedBox(height: 10),
Text(
'\$${loadedProduct.price}',
style: const TextStyle(
color: Colors.grey,
fontSize: 20,
),
),
const SizedBox(
height: 10,
),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.blueGrey.shade900),
onPressed: () {
saveData(Random().nextInt(1000));
},
child: const Text('Add to Cart')),
Container(
padding: const EdgeInsets.symmetric(horizontal: 10),
width: double.infinity,
child: Text(
loadedProduct.description,
textAlign: TextAlign.center,
softWrap: true,
),
),
],
),
);
})
);
}
}
Product Repository Dart file:
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:MyShoppingApp/db/cart_database.dart';
//add product data
import 'package:MyShoppingApp/model/product.dart';
//to get all products at once or any particular product by its ID
//product class that uses mixins with ChangeNotifier
class ProductsRepository with ChangeNotifier {
DBHelper dbHelper = DBHelper();
static List<Product> loadProducts(Category category) {
//linked list storing objects of type Product
var allProducts = <Product>[
Product(
category: Category.accessories,
id: "0",
isFeatured: true,
name: 'Vagabond sack',
price: 120,
details: "Nice fancy shirt",
description: "Comfortable and minimalistic",
image: "packages/shrine_images/0-0.jpg",
),
Product(
category: Category.accessories,
id: "1",
isFeatured: true,
name: 'Stella sunglasses',
price: 58,
details: "",
description: "",
image: "packages/shrine_images/1-0.jpg",
),
Product(
category: Category.accessories,
id: "2",
isFeatured: false,
name: 'Whitney belt',
price: 35,
details: "",
description: "",
image: "packages/shrine_images/2-0.jpg",
),
Product(
category: Category.accessories,
id: "3",
isFeatured: true,
name: 'Garden strand',
price: 98,
details: "",
description: "",
image: "packages/shrine_images/3-0.jpg",
),
Product(
category: Category.accessories,
id: "4",
isFeatured: false,
name: 'Strut earrings',
price: 34,
details: "",
description: "",
image: "packages/shrine_images/4-0.jpg",
),//removed other products to save space
];
if (category == Category.all) {
return allProducts;
} else {
return allProducts.where((Product p) {
return p.category == category;
}).toList();
}
}
//to get particular products by ID
Product findById(String id) {
var x = loadProducts(Category.all).firstWhere((prod) => prod.id == id);
print("findById successful");
print(x);
return x;
}
void addProduct() {
// _items.add(value);
notifyListeners();
}
}
Thank you everyone! Also, this problem stemmed from an earlier error in another post that a user was helping me to work through, but I didn't want to trouble them too much so I am reposting it here. Thank you @eamirho3ein