使用 ReorderableList 解決 Bloc 在 ListView 中頻繁的關閉與創建問題
最近在開發 Flutter app 時遇到了一個問題:當 ListView
中,每個 child 都使用 BlocProvider
,例如:
class MyListView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocSelector<RootCubit, RootState, List<SomeObj>>(
selector: (state) => state.items,
builder: (_, items) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (_, index) {
return BlocProvider(
create: (_) => MyCubit(),
child: ListTile(
key: ValueKey(items[index]),
title: Text(items[index].title),
),
);
},
);
},
);
}
}
如果列表的順序變更,child cubit 將會頻繁地被關閉與重新創建。此時會導致所有的 child 都不能再 emit state,否則會發生錯誤:
[ERROR: flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: Cannot emit new states after calling close
#0 BlocBase.emit (package:bloc/src/bloc_base.dart:97:9)
#1 MyCubit.fetchData.<anonymous closure> (package: myapp/features/hello/presentation/blocs/cubit.dart:203:13)
#2 GreetingRepository.fetchData(package:myapp/features/hello/infrastructure/repositories.dart:167:20)
‹asynchronous suspension>
#3 GreetingRepository.fetch.<anonymous closure (package:myapp/features/hello/infrastructure/repositories.dart:60:9)
<asynchronous suspension>
即便在每個 child 上增加了唯一的 key
,也無法解決這個問題。