Flutter Bloc 不更新 ui
Flutter Bloc does not update ui
我想在每次用户增加购物车时更新计数器,但我无法这样做,因为 bloc 不调用 bloc 生成器。
我是新手所以如果我没有正确表达我的问题请原谅我。
我认为这是因为我每次都产生相同的状态,但我没有找到任何解决方案。
请帮帮我
这是我的 bloc 文件。
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:brooklyn_bites/Infrastructure/core/app_database.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:injectable/injectable.dart';
part 'manage_cart_state.dart';
part 'manage_cart_event.dart';
part 'manage_cart_bloc.freezed.dart';
@injectable
class ManageCartBloc extends Bloc<ManageCartEvent, ManageCartState> {
ManageCartBloc(this.db) : super(ManageCartState.initial());
final AppDatabase db;
@override
Stream<ManageCartState> mapEventToState(ManageCartEvent gEvent) async* {
if (gEvent is _AddItemToCart) {
yield state.copyWith(
cartItems: List.from(
state.cartItems
..add(
CartItems(
productId: gEvent.product.id,
quantity: gEvent.quantity,
),
),
),
);
}
if (gEvent is _RemoveItemFromCart) {
yield state.copyWith(
cartItems: List.from(state.cartItems
..remove(CartItems(
productId: gEvent.product.id, quantity: gEvent.quantity))));
}
if (gEvent is _UpdateCartItem) {
yield state.copyWith(
cartItems: List.from(state.cartItems)
..where((element) => element.productId == gEvent.productId)
.first
.quantity += 1,
);
}
}
}
这是我的bloc_builder
class CartCounter extends StatelessWidget {
final Product product;
const CartCounter({Key key, this.product}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocBuilder<ManageCartBloc, ManageCartState>(
builder: (context, state) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
if (state.cartItems.isEmpty ||
state.cartItems
.where((element) => element.productId == product.id)
.isEmpty)
Container()
else
IconButton(
icon: Icon(
Icons.remove_circle_outline,
color: Colors.yellow[700],
),
onPressed: () {
state.cartItems
.where((element) =>
element.productId == product.id)
.isNotEmpty ??
context.bloc<ManageCartBloc>().add(
ManageCartEvent.removeItemFromCart(
product: product,
quantity: state.cartItems
.where((element) =>
element.productId == product.id)
.first
.quantity--,
),
);
}),
Text(
state.cartItems.isEmpty ||
state.cartItems
.where(
(element) => element.productId == product.id)
.isEmpty
? '0'
: state.cartItems
.where((element) => element.productId == product.id)
.first
.quantity
.toString(),
style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 18),
),
IconButton(
icon: Icon(
Icons.add_circle_outline,
color: Colors.yellow[700],
),
onPressed: () {
state.cartItems
.where((element) => element.productId == product.id)
.isNotEmpty
? context.bloc<ManageCartBloc>().add(
ManageCartEvent.updateCartItem(
productId: product.id))
: context.bloc<ManageCartBloc>().add(
ManageCartEvent.addItemToCart(
product: product,
quantity: 1,
),
);
},
),
],
),
],
);
},
);
}
}
我遇到了同样的问题,您可以使用 flutter clean
清理您的项目并重新运行该项目。如果它没有帮助,您可以使用 BlocConsumer 小部件来处理 bloc 状态。我推荐你看bloc timer project.
在我的例子中,我没有覆盖 CartItems 的哈希码 & ==。我可以使用 Freeezed Union 完成此操作(也可以使用 Equatable 完成)。
Imp 注意:如果您的州扩展了 Equatable,那么所有属性也需要扩展 Equatable。
我想在每次用户增加购物车时更新计数器,但我无法这样做,因为 bloc 不调用 bloc 生成器。 我是新手所以如果我没有正确表达我的问题请原谅我。
我认为这是因为我每次都产生相同的状态,但我没有找到任何解决方案。
请帮帮我
这是我的 bloc 文件。
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:brooklyn_bites/Infrastructure/core/app_database.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:injectable/injectable.dart';
part 'manage_cart_state.dart';
part 'manage_cart_event.dart';
part 'manage_cart_bloc.freezed.dart';
@injectable
class ManageCartBloc extends Bloc<ManageCartEvent, ManageCartState> {
ManageCartBloc(this.db) : super(ManageCartState.initial());
final AppDatabase db;
@override
Stream<ManageCartState> mapEventToState(ManageCartEvent gEvent) async* {
if (gEvent is _AddItemToCart) {
yield state.copyWith(
cartItems: List.from(
state.cartItems
..add(
CartItems(
productId: gEvent.product.id,
quantity: gEvent.quantity,
),
),
),
);
}
if (gEvent is _RemoveItemFromCart) {
yield state.copyWith(
cartItems: List.from(state.cartItems
..remove(CartItems(
productId: gEvent.product.id, quantity: gEvent.quantity))));
}
if (gEvent is _UpdateCartItem) {
yield state.copyWith(
cartItems: List.from(state.cartItems)
..where((element) => element.productId == gEvent.productId)
.first
.quantity += 1,
);
}
}
}
这是我的bloc_builder
class CartCounter extends StatelessWidget {
final Product product;
const CartCounter({Key key, this.product}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocBuilder<ManageCartBloc, ManageCartState>(
builder: (context, state) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
if (state.cartItems.isEmpty ||
state.cartItems
.where((element) => element.productId == product.id)
.isEmpty)
Container()
else
IconButton(
icon: Icon(
Icons.remove_circle_outline,
color: Colors.yellow[700],
),
onPressed: () {
state.cartItems
.where((element) =>
element.productId == product.id)
.isNotEmpty ??
context.bloc<ManageCartBloc>().add(
ManageCartEvent.removeItemFromCart(
product: product,
quantity: state.cartItems
.where((element) =>
element.productId == product.id)
.first
.quantity--,
),
);
}),
Text(
state.cartItems.isEmpty ||
state.cartItems
.where(
(element) => element.productId == product.id)
.isEmpty
? '0'
: state.cartItems
.where((element) => element.productId == product.id)
.first
.quantity
.toString(),
style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 18),
),
IconButton(
icon: Icon(
Icons.add_circle_outline,
color: Colors.yellow[700],
),
onPressed: () {
state.cartItems
.where((element) => element.productId == product.id)
.isNotEmpty
? context.bloc<ManageCartBloc>().add(
ManageCartEvent.updateCartItem(
productId: product.id))
: context.bloc<ManageCartBloc>().add(
ManageCartEvent.addItemToCart(
product: product,
quantity: 1,
),
);
},
),
],
),
],
);
},
);
}
}
我遇到了同样的问题,您可以使用 flutter clean
清理您的项目并重新运行该项目。如果它没有帮助,您可以使用 BlocConsumer 小部件来处理 bloc 状态。我推荐你看bloc timer project.
在我的例子中,我没有覆盖 CartItems 的哈希码 & ==。我可以使用 Freeezed Union 完成此操作(也可以使用 Equatable 完成)。 Imp 注意:如果您的州扩展了 Equatable,那么所有属性也需要扩展 Equatable。