I am trying to create an AnimatedList
using bloc
pattern, but ran into some problems.
When I am setting initialItemsCount of AnimatedList
to state.itemList.length
, it does not build. Although when I am printing out state.itemList
(that comes from ListBloc
) in BlocConsumer
's listener it prints out the itemList
.
So, the question is why is this not working?
I tried to do the same with ListView.builder
and it works fine. Am I missing something or the AnimatedList
is not even supposed to work using bloc?
Here is some sample code, made it super simple for this case:
MyApp class:
class _MyAppState extends State<MyApp> {
final key = GlobalKey<AnimatedListState>();
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => ListBloc()..add(LoadList()),
child: MaterialApp(
home: SafeArea(
child: BlocConsumer<ListBloc, ListState>(
listener: (_, state) {
print(state.itemList);
},
builder: (context, state) => Scaffold(
body: Column(
children: [
Expanded(
child: AnimatedList(
key: key,
initialItemCount: state.itemList.length,
itemBuilder: (context, index, animation) {
return Item(
animation: animation,
index: index,
text: state.itemList[index],
onTap: () => removeItem(index, state.itemList));
},
),
),
],
),
),
),
),
),
);
}
void removeItem(int index, List<String> items) {
final item = items.removeAt(index);
key.currentState?.removeItem(
index,
(context, animation) => Item(
animation: animation,
index: index,
text: items[index],
onTap: () => removeItem(index, items)));
}
}
Item class:
class Item extends StatelessWidget {
final Animation<double> animation;
final int index;
final String text;
final VoidCallback onTap;
const Item(
{required this.animation,
required this.index,
required this.text,
required this.onTap,
Key? key})
: super(key: key);
@override
Widget build(BuildContext context) {
return ScaleTransition(
scale: animation,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
onTap: onTap,
child: Container(
color: Colors.blue,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(text),
),
)),
),
);
}
}
Bloc:
class ListEvent extends Equatable {
const ListEvent();
@override
List<Object> get props => [];
}
class LoadList extends ListEvent {}
class ListState extends Equatable {
final List<String> itemList;
const ListState({required this.itemList});
@override
List<Object> get props => [itemList];
}
class ListBloc extends Bloc<ListEvent, ListState> {
ListBloc() : super(ListState(itemList: []));
@override
Stream<ListState> mapEventToState(ListEvent event) async* {
if (event is LoadList) {
var items = ['1', '2', '3', '4', '5', '6'];
yield ListState(itemList: items);
}
}
}
Thanks!