List.contains () не работает со списком документов fireshore - PullRequest
1 голос
/ 24 марта 2020

У меня есть список, который содержит несколько документов и снимков. когда я делаю list.contains (documentsnapshot), он всегда возвращает false. пример:

DocumentSnapshot a = document;
List<DocumentSnapshot> snapshots = []
snapshots.add(a);

snapshots.contains(a) // false

урезанная версия фактического кода

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class AddUsersDialog extends StatefulWidget {

  @override
  _AddUsersDialogState createState() => _AddUsersDialogState();
}

class _AddUsersDialogState extends State<AddUsersDialog> {

  List<DocumentSnapshot> selected = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: Container(
        child: Column(
          children: <Widget>[
            // row to display the selected users
            Row(
              children: List.generate(selected.length,
                (index) => InkWell(
                   onTap: () => setState(() => selected.removeAt(index)),
                   child: Text(selected[index]['name']),
                 );
              ),
            ),
            // list of all users
            StreamBuilder<QuerySnapshot>(
                stream: getUsers(),
                builder: (BuildContext context,
                    AsyncSnapshot<QuerySnapshot> snapshot) {
                  if (snapshot.hasData) {
                    List<DocumentSnapshot> users = snapshot.data.documents;
                    return Flexible(
                      child: ListView.builder(
                        itemCount: users.length,
                        itemBuilder: (BuildContext context, int index) {
                          return ListTile(
                            leading: Text(users[index]['name']),
                            onTap: () => setState(() {
                              if (selected.contains(users[index])) return;
                              selected.add(users[index]);
                            }),
                          );
                        },
                      ),
                    );
                  } 
                }
             ),
          ],
        ),
      ),
    );
  }
} 

Я получаю данные Streambuilder, они хорошо отображаются, я могу добавить documentSnapshots в выбранный список и я могу удалить их снова. только когда я проверяю в списке пользователей, если пользователь уже находится в выбранном списке, он всегда будет возвращать значение false, хотя при печати списка и пользователя я вижу, что он там есть.

Решение Очевидно, что прямое сравнение DocumentSnapshots приведет к проблемам, как описано в комментариях к ответу Мореза. Я решил это путем создания пользовательской функции

bool contains(List<DocumentSnapshot> list, DocumentSnapshot item) {
    for (DocumentSnapshot i in list) {
      if (i.documentID == item.documentID) return true;
    }
    return false;
  }

1 Ответ

2 голосов
/ 24 марта 2020

Я только что запустил похожий код, но он работает, как и ожидалось. Убедитесь, что ваш документ не пуст, потому что это может быть проблемой. Но если вы успешно добавите документ, вы получите snapshots.contains (a) как true.

Обновленный ответ

Мне кажется, проблема в том, что вы сравниваете объекты , Когда вы выполняете оператор if во второй раз, вы сравниваете два разных объекта с одинаковыми деталями, потому что каждый раз, когда вы запускаете конструктор, вы создаете новый объект в памяти. Таким образом, сравниваются 2 разных места в памяти, и результат всегда ложен, и поэтому вы всегда добавляете объект в список. Вы можете использовать идентичные (это и другие) или взглянуть на их коды ha sh, чтобы увидеть, что они являются разными объектами.

Решение состоит в том, чтобы найти что-то уникальное из объектов и сравни их. Вы можете проверить их идентификатор или имя, и если они разные, пользователи разные, а затем вы добавите его в свой список.

Вы также можете взглянуть на this .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...