在Listview.builder

时间:2020-03-18 10:17:54

标签: flutter dart flutter-animation

我正在尝试基于friendlychat example创建一个扑朔迷离的聊天应用。使用StreamBuilder(或者在我的情况下实际上是BlocBuilder),使用Firefire快照流中的消息填充ListView。我希望所有的消息都显示在聊天打开时,如图中所示。另外,当新消息从另一个用户或当前用户添加到Firestore集合中时,我希望一次从最底层的一个动画化新消息,而不是一次全部动画。这是我的问题。

所以看来我需要找出来自流的消息列表中的哪些项是新的。我只是通过考虑新列表与旧列表的长度差异来解决这一问题。然后,我尝试使用ListView.builder(请参见代码)中的AnimationController.forward()为基于长度差异的列表中的新项目设置动画。从其他用户收到消息时,此方法有效,但从当前设备/用户发送时则无效。它开始播放动画,但是有一些错误的行为(结束得太快或什么)。必须有更好的方法来实现所需的行为。有什么建议?

enter image description here

body: BlocBuilder<ChatBloc, ChatState>(builder: (context, state) {
      if (state is ChatLoaded) {
        return Container(
          child: BlocBuilder<AuthBloc, AuthState>(
              builder: (context, authState) {
            final messages = state.messagesLoaded;

            if (listOfmsg.length != messages.length) {
              diff = messages.length - listOfmsg.length;
              listOfmsg = messages;
              print(diff);
            } else {
              diff = 0;
            }

            final listBuilder = ListView.builder(
              padding: new EdgeInsets.all(8),
              reverse: true,
              itemBuilder: (_, int index) {
                final message = messages[index];

                if (index <= diff - 1) {
                  var msg = ChatMessageWithAnimation(
                    child: ChatMessage(
                      message: message,
                      userId: authState is AuthAuthenticated
                          ? authState.userId
                          : null,
                    ),
                    animationController: new AnimationController(
                        vsync: this,
                        duration: new Duration(milliseconds: 1400)),
                  );
                  msg.animationController.forward();
                  return msg;
                }

                return ChatMessage(
                  message: message,
                  userId: authState is AuthAuthenticated
                      ? authState.userId
                      : null,
                );
              },
              itemCount: messages.length,
            );

            return Column(
              children: <Widget>[
                Flexible(
                  child: listBuilder,
                ),
                new Divider(height: 1),
                new Container(
                  decoration:
                      new BoxDecoration(color: Theme.of(context).cardColor),
                  child: _buildTextComposer(authState is AuthAuthenticated
                      ? authState.userId
                      : null),
                ),
              ],
            );
          }),
          decoration: Theme.of(context).platform == TargetPlatform.iOS
              ? new BoxDecoration(
                  border:
                      Border(top: new BorderSide(color: Colors.grey[200])))
              : null,
        );
      }
      return Container();
    }));
class ChatMessageWithAnimation extends StatelessWidget {
  ChatMessageWithAnimation({this.child, this.text, this.animationController});

  final String text;
  final AnimationController animationController;
  final Widget child;
  @override
  Widget build(BuildContext context) {
    return new SizeTransition(
        sizeFactor: new CurvedAnimation(
            parent: animationController, curve: Curves.easeOut),
        child: this.child);
  }
}

0 个答案:

没有答案