flutter 使用ListView.custom添加分隔符

jjhzyzn0  于 2023-05-29  发布在  Flutter
关注(0)|答案(1)|浏览(233)

我想使用ListView.custom来创建一个以日期为分隔符的聊天列表。我使用了ListView.separated,但这会在重建聊天消息时拖慢性能,而只使用ListView.custom就可以完美地工作。我只需要现在能够添加在日期每半小时。下面是我的ListView.separated代码:

ListView.separated(
                      controller: messageScrollController,
                      reverse: true,
                      itemCount: messages.length + 1,
                      separatorBuilder: (context, index) {
                        if (index == messages.length - 1) {
                          return DateLabel(date: messages[index].createdAt);
                        }
                        if (messages.length == 1) {
                          return const SizedBox.shrink();
                        } else if (index >= messages.length - 1) {
                          return const SizedBox.shrink();
                        } else if (index <= messages.length) {
                          final message = messages[index];
                          final nextMessage = messages[index + 1];
                          if (!Jiffy.parseFromDateTime(
                                  message.createdAt.toLocal())
                              .isSame(
                                  Jiffy.parseFromDateTime(
                                      nextMessage.createdAt.toLocal()),
                                  unit: Unit.day)) {
                            return DateLabel(date: message.createdAt);
                          } else {
                            return const SizedBox.shrink();
                          }
                        } else {
                          return const SizedBox.shrink();
                        }
                      },
                      findChildIndexCallback: (key) {
                        final valueKey = key as ValueKey<String>;
                        final val = messages.indexWhere(
                            (element) => element.id == valueKey.value);
                        if (val < messages.length) {
                          return val;
                        } else {
                          return val + 1;
                        }
                      },
                      itemBuilder: (context, index) {
                        if (index < messages.length) {
                          final message = messages[index];

                          return AutoScrollTag(
                            key: ValueKey(message.id),
                            controller: messageScrollController,
                            index: index,
                            child: Padding(
                              padding: index == 0
                                  ? const EdgeInsets.only(bottom: 20)
                                  : EdgeInsets.zero,
                              child: SwipeTo(
                                onRightSwipe:
                                    widget.currentUser.id == message.user.id
                                        ? null
                                        : () {
                                            onSwipedMessage(message);
                                          },
                                onLeftSwipe:
                                    widget.currentUser.id != message.user.id
                                        ? null
                                        : () {
                                            onSwipedMessage(message);
                                          },
                                child: MessageBubble(
                                  key: ValueKey(message.id),
                                  message: message,
                                  userProfile: widget.currentUser,
                                  nextMessage: getNext(index),
                                  previousMessage: getPrevious(index),
                                  hasEmoji:
                                      hasOnlyEmojis(message.messageText ?? ''),
                                  isMe:
                                      widget.currentUser.id == message.user.id,
                                  toMessage: scrollToMessage,
                                ),
                              ),
                            ),
                          );
                        } else {
                          return const SizedBox.shrink();
                        }
                      },
                    )
ibrsph3r

ibrsph3r1#

我发现这样做的方法是使用索引的~/ 2,与SliverList.separated的方法相同:

ListView.custom(
                      controller: messageScrollController,
                      reverse: true,
                      keyboardDismissBehavior:
                          ScrollViewKeyboardDismissBehavior.onDrag,
                      childrenDelegate: SliverChildBuilderDelegate(
                        (context, index) {
                          final int itemIndex = index ~/ 2;
                          Widget? listWidget;
                          log('index: $itemIndex');
                          if (index.isEven) {
                            if (itemIndex < messages.length) {
                              final message = messages[itemIndex];

                              listWidget = AutoScrollTag(
                                key: ValueKey(message.id),
                                controller: messageScrollController,
                                index: index,
                                child: Padding(
                                  padding: index == 0
                                      ? const EdgeInsets.only(bottom: 20)
                                      : EdgeInsets.zero,
                                  child: SwipeTo(
                                    onRightSwipe:
                                        widget.currentUser.id == message.user.id
                                            ? null
                                            : () {
                                                onSwipedMessage(message);
                                              },
                                    onLeftSwipe:
                                        widget.currentUser.id != message.user.id
                                            ? null
                                            : () {
                                                onSwipedMessage(message);
                                              },
                                    child: MessageBubble(
                                      key: ValueKey(message.id),
                                      message: message,
                                      userProfile: widget.currentUser,
                                      nextMessage: getNext(index),
                                      previousMessage: getPrevious(index),
                                      hasEmoji: hasOnlyEmojis(
                                          message.messageText ?? ''),
                                      isMe: widget.currentUser.id ==
                                          message.user.id,
                                      toMessage: scrollToMessage,
                                    ),
                                  ),
                                ),
                              );
                            } else {
                              listWidget = const SizedBox.shrink();
                            }
                          } else {
                            if (itemIndex == messages.length - 1) {
                              listWidget = DateLabel(
                                  date: messages[itemIndex].createdAt);
                            }
                            if (messages.length == 1) {
                              listWidget = const SizedBox.shrink();
                            } else if (itemIndex >= messages.length - 1) {
                              listWidget = const SizedBox.shrink();
                            } else if (itemIndex <= messages.length) {
                              final message = messages[itemIndex];
                              final nextMessage = messages[itemIndex + 1];
                              if (!Jiffy.parseFromDateTime(
                                      message.createdAt.toLocal())
                                  .isSame(
                                      Jiffy.parseFromDateTime(
                                          nextMessage.createdAt.toLocal()),
                                      unit: Unit.day)) {
                                listWidget = DateLabel(date: message.createdAt);
                              } else {
                                listWidget = const SizedBox.shrink();
                              }
                            } else {
                              listWidget = const SizedBox.shrink();
                            }
                          }
                          return listWidget;
                        },
                        childCount: messages.length + 1,
                        findChildIndexCallback: (key) {
                          final valueKey = key as ValueKey<String>;
                          final val = messages.indexWhere(
                              (element) => element.id == valueKey.value);
                          return val;
                        },
                      ),
                    )

相关问题