每当我调用toggleLocked事件时,BlocBuilder都不会重新构建小部件。
我在互联网上看了很多,找到了这样的解释:https://stackoverflow.com/a/60869187/3290471我认为我错误地使用了equatable包,这导致了BlocBuilder认为什么都没有改变(而is已经改变了)。
我已经阅读了来自Bloc libray的常见问题解答,并且提供的三个解决方案(支持equatable /不重用相同的状态/使用fromList)似乎不能解决问题。
我的Cubit:
class LockCubit extends Cubit<LockState> {
LockCubit({@required this.repository})
: assert(repository != null),
super(LockInitial());
final LocksRepository repository;
Future<void> fetch() async {
try {
final locks = await repository.fetchLocks();
emit(LocksDisplayed().copyWith(locks));
} on Exception {
emit(LockError());
}
}
Future<void> toggleLocked(int id) async {
try {
final locks = await repository.toggleLocked(id);
emit(LocksDisplayed().copyWith(List.from(locks)));
} on Exception {
emit(LockError());
}
}
}我的状态:
abstract class LockState extends Equatable {
const LockState();
@override
List<Object> get props => [];
}
class LockInitial extends LockState {
@override
String toString() => 'LocksUninitialized';
}
class LockError extends LockState {
@override
String toString() => 'LockError';
}
class LocksDisplayed extends LockState {
final List<Lock> locks;
const LocksDisplayed([this.locks = const []]);
LocksDisplayed copyWith(locks) => LocksDisplayed(locks ?? this.locks);
@override
List<Object> get props => [locks];
@override
String toString() => 'LocksDisplayed { locks: $locks }';
}我的模型:
class Lock extends Equatable {
Lock({this.id, this.name, this.locked, this.displayed});
final int id;
final String name;
final bool locked;
final bool displayed;
@override
String toString() =>
'Lock { id: $id name: $name locked: $locked displayed: $displayed }';
Lock copyWith({id, name, locked, displayed}) => Lock(
id: id ?? this.id,
name: name ?? this.name,
locked: locked ?? this.locked,
displayed: displayed ?? this.displayed);
@override
List<Object> get props => [id, name, locked, displayed];
}我的存储库:
class LocksRepository {
List<Lock> locks = [];
Future<List<Lock>> fetchLocks() async {
// This is a temporary implementation
// In the future the data should be fetched from a provider
locks = [
new Lock(
id: 0,
name: 'Voordeur',
locked: false,
),
new Lock(
id: 1,
name: 'Achterdeur',
locked: false,
)
];
return locks;
}
Future<List<Lock>> toggleLocked(int id) async {
// This is a temporary implementation
// In the future a request to change a lock should be made and then the specific lock should be retrieved back and edited.
locks[id] = locks[id].copyWith(locked: !locks[id].locked);
return locks;
}
}我正在使用以下触发器更改状态:
context.read<LockCubit>().toggleLocked(focusedIndex);我像这样使用BlocBuilder来构建状态:
BlocBuilder<LockCubit, LockState>(builder: (context, state) {
print('State Changed');
if (state is LockInitial) {
return Text('lockInitial');
}
if (state is LocksDisplayed) {
return Swiper(
itemBuilder: (BuildContext context, int index) {
return Column(
children: [
Text(state.locks[index].name),
Text(state.locks[index].locked.toString())
],
);
},
onIndexChanged: onIndexChanged,
loop: true,
itemCount: state.locks.length);
}
if (state is LockError) {
return Text('lockError');
}
return Container();
});所有的帮助都将不胜感激。
发布于 2020-12-15 18:41:41
你能查一下BlocProvider吗?我也有同样的问题。如果此阻塞位于materialApp内部,则必须传递BlocProvider.value,而不是在小部件中创建。
发布于 2020-12-01 21:06:18
如果这能行得通,我有点困惑。但是对于bloc,您将使用事件,而不是cubit (即使事件是基于cubit的)。
因此,首先我将使用标准模式:使用mapEventToState进行状态事件阻塞
然后,我在你的代码中也看不到的是,如果你切换你的锁,它在伪代码中会是这样的
if (event is toggleLock) {
yield lockInProgress();
toggleLock();
yield locksDisplayed;
}这样,您的状态总是从locksDisplayed更改为lockInProgress,再更改为locksDisplayed -正如您在上面的链接中所看到的那样
https://stackoverflow.com/questions/65090423
复制相似问题