我正在建立一个flutter电子商务应用程序,我有一个问题,如果我点击添加到收藏夹按钮,它选择所有项目,而不是选定的特定项目。我的项目是在一个网格视图使用标签栏。请任何人可以帮助。
以下是选择
之前的项目
然后在选择之后(如您所见,所有项目均已选中)
下面是我的代码模型:
//Bottle and Bottle Category Model classes
class Bottle with ChangeNotifier {
String id;
String bottleName;
String image;
String bottletype;
int time;
double price;
bool isFavourite;
Bottle(
{required this.id,
required this.bottleName,
required this.image,
required this.bottletype,
required this.time,
required this.price,
this.isFavourite = false});
void isFavoritePressed() {
isFavourite = !isFavourite;
notifyListeners();
}
}
class BottleCategory {
int categoryNo;
String bottleType;
List<Bottle> bottleList;
BottleCategory(
{required this.categoryNo,
required this.bottleType,
required this.bottleList});
}
//Cart Model Class
class Cart with ChangeNotifier {
String id;
String bottleName;
String image;
double price;
int quantity;
Cart({
required this.id,
required this.bottleName,
required this.image,
required this.price,
required this.quantity,
});
}
class ProductItem extends StatelessWidget {
HomePage homeInstance = const HomePage();
String id;
String bottleName;
String imgUrl;
double price;
bool isFavourite;
ProductItem(
{Key? key,
required this.id,
required this.bottleName,
required this.imgUrl,
required this.price,
this.isFavourite = false})
: super(key: key);
@override
Widget build(BuildContext context) {
var cart = Provider.of<ShoppingCartProvider>(context);
var product = Provider.of<Bottle>(context);
return Card(
shadowColor: Colors.grey,
surfaceTintColor: Colors.amber,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
child: Stack(
children: [
Positioned(
right: 0,
child: InkWell(
onTap: () {
product.isFavoritePressed();
if (product.isFavourite) {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
"Product Added to Favorite!",
style: TextStyle(fontSize: 16),
),
backgroundColor: Colors.green,
duration: Duration(seconds: 1),
),
);
} else {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
"Product Removed from Favorite!",
style: TextStyle(fontSize: 16),
),
backgroundColor: Colors.red,
duration: Duration(seconds: 1),
),
);
}
},
child: Icon(
product.isFavourite ? Icons.favorite : Icons.favorite_border,
size: 25,
color: Colors.redAccent,
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Image.asset(
imgUrl,
height: 200.0,
),
),
Center(
child: Text(bottleName,
style: const TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold))),
Center(
child: Text('R$price'),
)
],
),
Positioned(
bottom: 0,
right: 10,
child: IconButton(
icon: const Icon(Icons.add_circle),
iconSize: 40.0,
onPressed: () {
cart.addToCart(id, bottleName, price, imgUrl);
},
))
],
),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
ProductProvider productProvider = ProductProvider();
late TabController tabController;
late Bottle bottleProvider;
String query = " ";
Widget buildSearch() {
return SearchWidget(
text: query,
hintText: 'Search for beverages',
onChanged: (value) {
setState(() {
this.query = value;
});
},
);
}
@override
void initState() {
super.initState();
tabController = TabController(length: 4, vsync: this);
}
@override
void dispose() {
tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
var cart = Provider.of<ShoppingCartProvider>(context);
Size _screenSize = MediaQuery.of(context).size;
final double itemHeight = (_screenSize.height - kToolbarHeight - 24) / 2;
final double itemWidth = _screenSize.width / 2;
return Scaffold(
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildSearch(),
const Padding(
padding: EdgeInsets.all(8.0),
child: Text(
'Categories',
style: TextStyle(
fontSize: 20.0,
fontFamily: 'Montserrat-ExtraBold',
fontWeight: FontWeight.bold),
),
),
Container(
child: Align(
alignment: Alignment.centerLeft,
child: TabBar(
controller: tabController,
indicator:
CircleTabIndicator(color: Colors.redAccent, radius: 4.0),
isScrollable: true,
labelColor: Colors.redAccent,
labelStyle: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 20.0),
unselectedLabelColor: Colors.black,
unselectedLabelStyle: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 20.0),
tabs: const [
Tab(text: 'Brandy'),
Tab(text: 'Gin'),
Tab(text: 'Soft drinks'),
Tab(text: 'Whiskey')
],
),
),
),
Container(
height: 400,
width: double.maxFinite,
child: TabBarView(
controller: tabController,
children: productProvider.categories.map((bottleCategory) {
return GridView.count(
crossAxisCount: 2,
childAspectRatio: itemWidth / itemHeight,
children: bottleCategory.bottleList.where((element) {
return element.bottleName.toLowerCase().contains(
query.toLowerCase()); // Apply the query string
}).map((bottle) {
return ProductItem(
id: bottle.id,
bottleName: bottle.bottleName,
imgUrl: bottle.image,
price: bottle.price,
);
}).toList(),
);
}).toList()),
),
],
),
),
);
}
}
//ProductProvider
class ProductProvider with ChangeNotifier {
final List<BottleCategory> categories = [
BottleCategory(categoryNo: 1, bottleType: 'Brandy', bottleList: [
Bottle(
id: 'KLPB',
bottleName: 'Klipdrift Brandy',
image: 'lib/assets/images/KlipdriftBrandy.png',
time: 20,
price: 274.00,
bottletype: 'Brandy'),
Bottle(
id: 'KWV3',
bottleName: 'Kwv Brandy 3 years',
image: 'lib/assets/images/KwvBrandy3years.jpg',
time: 20,
price: 274.00,
bottletype: 'Brandy'),
]),
BottleCategory(categoryNo: 2, bottleType: 'Gin', bottleList: [
Bottle(
id: 'BMBS',
bottleName: 'Bombay Sapphire Gin',
image: 'lib/assets/images/BombaySapphireGin.png',
time: 20,
price: 274.00,
bottletype: 'Gin'),
Bottle(
id: 'TNGN',
bottleName: 'Tanqueray Gin',
image: 'lib/assets/images/TanquerayGin.png',
time: 20,
price: 274.00,
bottletype: 'Gin'),
]),
BottleCategory(categoryNo: 3, bottleType: 'Soft Drinks', bottleList: [
Bottle(
id: 'COCA',
bottleName: 'Coca Cola',
image: 'lib/assets/images/CocaCola.jpg',
time: 20,
price: 274.00,
bottletype: 'Soft Drinks'),
Bottle(
id: 'SPRT',
bottleName: 'Sprite',
image: 'lib/assets/images/Sprite.jpg',
time: 20,
price: 274.00,
bottletype: 'Soft Drinks'),
]),
BottleCategory(categoryNo: 4, bottleType: 'Whiskey', bottleList: [
Bottle(
id: '',
bottleName: 'Jameson',
image: 'lib/assets/images/Jameson.jpg',
time: 20,
price: 274.00,
bottletype: 'Whiskey'),
Bottle(
id: '',
bottleName: 'Johnnie Walker Black Label',
image: 'lib/assets/images/JohnnieWalkerBlackLabel.jpg',
time: 20,
price: 274.00,
bottletype: 'Whiskey'),
]),
];
List<Bottle> get bottleItems {
return [...bottleItems];
}
List<Bottle> get bottleObjects {
return [...bottleObjects];
}
get bottle => null;
List<Bottle> get selectedFavorite {
return categories
.expand((bottleCategory) {
return bottleCategory.bottleList;
})
.toList()
.where((bottle) {
return bottle.isFavourite;
})
.toList();
}
}
//Cart Provider
import 'package:flutter/cupertino.dart';
import 'package:test_code/cart.dart';
class ShoppingCartProvider with ChangeNotifier {
final Map<String, Cart> _cartItems = {};
Map<String, Cart> get cartItem {
return {..._cartItems};
}
void removeBottle(String id) {
_cartItems.remove(id);
notifyListeners();
}
void addToCart(
String id, String bottleName, double bottlePrice, String image) {
if (_cartItems.containsKey(id)) {
_cartItems.update(id, (existingItem) {
return Cart(
id: existingItem.id,
bottleName: existingItem.bottleName,
image: existingItem.image,
price: existingItem.price,
quantity: existingItem.quantity + 1);
});
} else {
_cartItems.putIfAbsent(id, () {
return Cart(
id: id,
bottleName: bottleName,
image: image,
price: bottlePrice,
quantity: 1);
});
}
notifyListeners();
}
void addQuantity(String id) {
_cartItems.update(id, (existingItem) {
return Cart(
id: existingItem.id,
bottleName: existingItem.bottleName,
image: existingItem.image,
price: existingItem.price,
quantity: existingItem.quantity + 1);
});
notifyListeners();
}
void reduceQuantity(String id) {
_cartItems.update(id, (existingItem) {
if (existingItem.quantity == 1) {
return Cart(
id: existingItem.id,
bottleName: existingItem.bottleName,
image: existingItem.image,
price: existingItem.price,
quantity: existingItem.quantity);
} else {
return Cart(
id: existingItem.id,
bottleName: existingItem.bottleName,
image: existingItem.image,
price: existingItem.price,
quantity: existingItem.quantity - 1);
}
});
notifyListeners();
}
void clearCart() {
_cartItems.clear();
notifyListeners();
}
double get totalAmount {
double total = 0.0;
_cartItems.forEach((key, eachItem) {
total = total + eachItem.price * eachItem.quantity;
});
return total;
}
int get cartCount {
return _cartItems.length;
}
}
2条答案
按热度按时间fae0ux8s1#
你可以玩小工具来了解项目选择模式。
bvjveswy2#
我自己解决了这个问题。我只是把按钮移到一个单独的小部件上。我不知道它是怎么工作的,但它帮了我。