Flutter AnimatedList with BlocListener

461 Views Asked by At

I'm trying to get AnimatedList working with my current MessengerBloc which can accept MessengerEvent.pushed(Message) and MessengerBloc.popped(Message). When the state changes, it listens and compares the previous state with the current state to figure out which item index has to be added/removed/moved. Up to this point works so I removed those code for brevity.

Problem

When I add MessengerEvent.pushed(Message) this is the sequence of print statements:

message was added

building messages

[Message()] // from print(messages) in _buildOverlay()

index0: [] // from print('index$index: $messages') in AnimatedList.itemBuilder

index0: [Message()] // from print('index$index: $messages') in AnimatedList.itemBuilder

Question: Why is messages in AnimatedList.itemBuilder prints out emptyList, then runs again with the updated messages?

class MessageOverlay extends StatelessWidget {
  final GlobalKey<AnimatedListState> _animatedListKey = GlobalKey();

  Widget _buildOverlay(KtList<Message> messages) {
    print('building messages');
    print(messages);
    return AnimatedList(
      key: _animatedListKey,
      initialItemCount: messages.size,
      itemBuilder: (context, index, animation) {
        print('index$index: $messages');
        return const SizedBox.shrink();
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return BlocConsumer<MessengerBloc, MessengerState>(
      listener: (context, state) {
        // Message moved - Removed code for brevity
        if (messageMoved) {
          print('message was moved');
          _animatedListKey.currentState
              .removeItem(prevIndex, (context, animation) => null);
          _animatedListKey.currentState.insertItem(nextIndex);
        }
        // Message added - Removed code for brevity
        else if (messageAdded) {
          print('message was added');
          _animatedListKey.currentState.insertItem(nextIndex);
        }
        // Message removed - Removed code for brevity
        else if (messageRemoved) {
          print('message was removed');
          _animatedListKey.currentState
              .removeItem(prevIndex, (context, animation) => null);
        }
      },
      builder: (context, state) => _buildOverlay(state.messages),
    ),
  );
}
0

There are 0 best solutions below