Flutter / Firestore - Реализация «нумерации страниц» в динамическом просмотре списка в построителе потоков - PullRequest
1 голос
/ 10 июня 2019

У меня есть логика, и она работает, но я что-то упускаю, потому что единственный способ, которым это работает, - это когда я заменяю массив следующей «страницей» или документами, но когда я делаю .addAll(), он получает беспорядочный. Те же самые первые документы читаются и включаются несколько новых, но не все, что должно было быть включено.

код:

ScrollController _scrollController = ScrollController();
List<Message> _messages = [];
List<dynamic> _startAfter = [DateTime.now()];

...

@override
void initState() {
    super.initState();
    this._scrollController.addListener(() {
      if (this._scrollController.position.minScrollExtent + this._scrollController.position.pixels <= -15.0) {
        setState(() {
          this._startAfter = [this._messages.first.createdAt.toDate()];
        });
      }
    });
}

...

Column(
  children: <Widget>[
    Expanded(
      child: StreamBuilder<List<Message>>(
          stream: APIs().chats.messagesStream(chatID: widget.chat.chatID, orderBy: 'createdAt', descending: true, startAfter: this._startAfter, limit: 10),
          builder: (context, snapshot) {
            print(this._startAfter);
            switch (snapshot.connectionState) {
              case ConnectionState.waiting:
                {
                  return PAIndicator();
                }
              default:
                {
                  if (snapshot.hasData) {    
                    this._messages = snapshot.data; // Having the issue here.

                    // this._messages.addAll(snapshot.data); Causes problems when rebuilding

                    return MessagesList(
                      scrollController: this._scrollController,
                      messages: this._messages,
                      aUser: widget.aUser,
                    );
                  } else {
                    return ListView();
                  }
                }
            }
          }),
    ),
  // ...
  ]
)

Я заметил, что ошибка возникает только тогда, когда она перестраивается.

Когда данные извлекаются, они заменяют то, что находится в массиве, как я могу просто добавить данные вместо того, чтобы просто заменить их или дать несколько одинаковых значений одних и тех же сообщений, когда используется .addAll(), не беспокоясь о том, что пользовательский интерфейс будет перестроен как если клавиатура показывает и закрывает?

Кроме того, как я могу убедиться, что если документов больше нет, они не будут восстановлены или не вызовут firebase? (Решено, теперь остался только главный вопрос)

1 Ответ

0 голосов
/ 12 июня 2019

Разобрался с решением для всех, кому это нужно. Единственная проблема заключается в том, что элементы просто добавляются в список, чтобы он не выглядел достаточно UI / UX. Не стесняйтесь добавлять это решение, если оно у вас есть. Я попробовал AnimatedList, но это не сработало из-за проблемы с состоянием, и я пока не знаю, как это обойти.

ПРИМЕЧАНИЕ: ПО НЕКОТОРЫМ ПРИЧИНАМ ЭТОГО НЕ СЛУШАЕТСЯ НОВЫМИ СООБЩЕНИЯМИ ОТ ИГО ПОЛЬЗОВАТЕЛЯ, Я ДОЛЖЕН ВСТАВИТЬ В ЧАТ, ЧТОБЫ УВИДЕТЬ НОВЫЕ СООБЩЕНИЯ, помогите с этим, пожалуйста.

GlobalKey<AnimatedListState> _listKey = GlobalKey();
ScrollController _scrollController = ScrollController();
List<Message> _messages = [];
List<dynamic> _startAfter = [DateTime.now()];
int _messagesLimit = 10;
bool _hasMoreMessages = false;

@override
void initState() {
  super.initState();

  if (Platform.isIOS) {
    this._scrollController.addListener(() {
      if (this._scrollController.position.pixels >= this._scrollController.position.maxScrollExtent + 150.0) {
        this._checkForOldMessages();
      }
    });
  }
}

@override
Widget build(BuildContext context) {
  Widget w = WillPopScope(
      child: Stack(
        children: <Widget>[
          Column(
            children: <Widget>[
              Expanded(child: this._streamBuilderWidget()),
              // …
            ],
          ),
        ],
      ),
      onWillPop: () {});

  …
}

Widget _streamBuilderWidget() {
    return StreamBuilder<List<Message>>(
        initialData: this._messages,
        stream: APIs().chats.messagesStream(chatID: widget.chat.chatID, orderBy: 'createdAt', descending: true, startAfter: this._startAfter, limit: this._messagesLimit),
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
              {
                return PAIndicator();
              }
            default:
              {
                if (snapshot.data.length < this._messagesLimit) {
                  this._hasMoreMessages = false;
                } else {
                  this._hasMoreMessages = true;
                }

                snapshot.data.forEach((m) {
                  print(m.message);
                });

                if (!ListEquality().equals(this._messages, snapshot.data)) {
                  snapshot.data.forEach((m) {
                    this._messages.add(m);
                  });
                } else {
                  print('nonononono');
                }

                // Doesn't Work...
                // if (mounted) this._listKey.currentState.insertItem(this._messages.length - 1, duration: Duration(milliseconds: 500)); 

                return Platform.isIOS
                    ? MessagesList(mKey: this._listKey, scrollController: this._scrollController, messages: this._messages, aUser: widget.aUser)
                    : RefreshIndicator(
                    child: MessagesList(mKey: this._listKey, scrollController: this._scrollController, messages: this._messages, aUser: widget.aUser),
                    onRefresh: () async {
                      await Future.delayed(Duration(seconds: 1));

                      this._checkForOldMessages();

                      return null;
                    });
              }
          }
        });
  }

_checkForOldMessages() {
  if (this._hasMoreMessages) {
    print('Adding More...');
    setState(() {
      this._startAfter = [this._messages.last.createdAt.toDate()];
    });
    this._streamBuilderWidget();
  }
}
...