I'm working on a shopping app for a school project, and I'm trying to get my product images 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 - so all of my product images are in the assets folder.
I think I made some mistake with retrieving the images from assets because I received the following error in my product detail screen: Invalid Argument(s): No host specified in URI file...
and my images do not show up on any of the detail screens.
Here is the specific line of code in my product detail screen where I tried to retrieve the image:
I tried to backtrack by seeing where all these image variables are linked. Hovering over "image" in the code above gives me this showing that the image is a String in product.dart:
so I thought it would be useful to add the product.dart code here too:
//constructor for product
Product({
required this.category,
required this.id,
required this.name,
required this.price,
required this.details,
required this.description,
required this.isFeatured,
required this.image,
});
//declaring local instances
//class constructor to pass data
final Category category;
final String id;
final String name;
final int price;
final String details;
final String description;
final String image;
bool isFeatured;
void changeStateOfFavorite() {
isFeatured = !isFeatured;
notifyListeners();
}
String get assetName => '$id-0.jpg';
String get assetPackage => 'shrine_images'; //i think this is the line where it is linked to assets but I'm not sure if this is the problem
@override
String toString() => "$name (id=$id)";
findById(String productId) {}
Map toJson() {
return {
'id':id,
'name': name,
'price': price,
'image': image,
};
}
}
I'm very new to coding but I really need the help to get the project done, thank you to anyone who is willing to help! I appreciate it so much
Edit: endless listview scroll of image and product details
Edit 2: Listview builder code
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,
),
),
],
),
);
})
);
}
}
ProductRepository 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();
}
}
CodePudding user response:
Image.network
is for online image what you give it a url and it download the image. If you store all your image in assets folder inside app you should use Image.asset
, like this:
Image.asset(loadedProduct.image)