我正在尝试使用 CSV 数据集在 Flutter 中构建 Myntra 时尚应用程序。
这是我的代码:
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:csv/csv.dart';
import 'package:flutter/services.dart' show rootBundle;
// ignore: unused_import
import 'product.dart';
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<Product> _products = [];
List<Product> _filteredProducts = [];
bool _isLoading = true;
@override
void initState() {
super.initState();
_loadCsvData();
}
Future<void> _loadCsvData() async {
try {
final csvString =
await rootBundle.loadString('assets/myntra_fashion6.csv');
List<List<dynamic>> csvTable = CsvToListConverter().convert(csvString);
if (csvTable.isNotEmpty) {
print('CSV Table Headers: ${csvTable[0]}');
}
List<Product> products = [];
for (var i = 1; i < csvTable.length; i++) {
print('CSV Row $i: ${csvTable[i]}');
products.add(Product.fromCsv(csvTable[i]));
}
setState(() {
_products = products;
_filteredProducts = products;
_isLoading = false;
});
} catch (e) {
print("Error loading CSV data: $e");
}
}
void _filterProducts(String query) {
List<Product> filtered = _products.where((product) {
return product.brandName.toLowerCase().contains(query.toLowerCase()) ||
product.description.toLowerCase().contains(query.toLowerCase()) ||
product.category.toLowerCase().contains(query.toLowerCase());
}).toList();
setState(() {
_filteredProducts = filtered;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Myntra Fashion'),
bottom: PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
onChanged: (value) {
_filterProducts(value);
},
decoration: InputDecoration(
hintText: 'Search...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
contentPadding: EdgeInsets.all(16.0),
fillColor: Colors.white,
),
),
),
),
),
body: _isLoading
? Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: _filteredProducts.length,
itemBuilder: (context, index) {
return ProductCard(product: _filteredProducts[index]);
},
),
);
}
}
class ProductCard extends StatelessWidget {
final Product product;
ProductCard({required this.product});
@override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.all(8.0),
child: ListTile(
leading: Image.network(product.url,
width: 50, height: 50, fit: BoxFit.cover),
title: Text(product.brandName),
subtitle: Text(product.description),
trailing: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('₹${product.discountPrice.toStringAsFixed(2)}',
style: TextStyle(fontWeight: FontWeight.bold)),
Text('₹${product.originalPrice.toStringAsFixed(2)}',
style: TextStyle(decoration: TextDecoration.lineThrough)),
],
),
),
);
}
}
我尝试了几个调试步骤,但屏幕仍然卡在圆形加载指示器处。这是产品型号:
class Product {
final String url;
final int productId;
final String brandName;
final String category;
final String individualCategory;
final String categoryByGender;
final String description;
final double discountPrice;
final double originalPrice;
final int discountOffer;
final String sizeOption;
final double ratings;
final int reviews;
final String standardizedSize;
Product({
required this.url,
required this.productId,
required this.brandName,
required this.category,
required this.individualCategory,
required this.categoryByGender,
required this.description,
required this.discountPrice,
required this.originalPrice,
required this.discountOffer,
required this.sizeOption,
required this.ratings,
required this.reviews,
required this.standardizedSize,
});
factory Product.fromCsv(List<dynamic> csvRow) {
return Product(
url: csvRow[0],
productId: int.parse(csvRow[1]),
brandName: csvRow[2],
category: csvRow[3],
individualCategory: csvRow[4],
categoryByGender: csvRow[5],
description: csvRow[6],
discountPrice: double.parse(csvRow[7]),
originalPrice: double.parse(csvRow[8]),
discountOffer: int.parse(csvRow[9]),
sizeOption: csvRow[10],
ratings: double.parse(csvRow[11]),
reviews: int.parse(csvRow[12]),
standardizedSize: csvRow[13],
);
}
}
我应该怎么做才能在应用程序中正确显示 CSV 内容?
我尝试使用 print 语句调试代码,但收到此错误:
Error loading CSV data: RangeError (index): Index out of range: index should be less than 1: 1
从错误消息来看,可能是因为您正在尝试访问 Product 类中的 .fromCsv 方法中不存在的行元素。让我们看一下(假设
CsvToListConverter().convert(csvString);
不会抛出任何错误:
我建议您在迭代中添加一个断点,并检查您当时正在评估的
csvTable[i]
是否具有正确解析类所需的所有值。