Что упускаете, с подключением Firestore и ListView для случайных результатов в выборке?

Пытаюсь подключить свой Firestore к ListView. С моим Query помещаются 20 записей и 3 случайные из них, помещаются в ArrayList (randomPlaceList), затем я логично пытаюсь включить этот ArrayList в свой собственный adapter. Но я кое-что скучаю ..

EDITED с некоторыми переменными изменения; Теперь у меня такая ошибка:

Process: com.example.arara.myapplication, PID: 10283 java.lang.IndexOutOfBoundsException: Index: 4, Size: 0 at java.util.ArrayList.get(ArrayList.java:437) at com.example.arara.myapplication.MainActivity$1.onComplete(MainActivity.java:46)

В этой строке:

Peoples item = randomPlaceList.get(randomIndex);

ListViewPlaces класс:

public class MainActivity extends AppCompatActivity {

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference placeRef = rootRef.collection("peoples");

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    placeRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(Task<QuerySnapshot> task) {
            if (task.isSuccessful()) {
                List<Peoples> peoplesList = new ArrayList<>();
                for (DocumentSnapshot document : task.getResult()) {
                    Peoples peoples = document.toObject(Peoples.class);
                    System.out.println(peoples);
                    peoplesList.add(peoples);
                }
                if (peoplesList.size() > 0) {
                    System.out.println(peoplesList);
                    int placeCount = peoplesList.size();
                    Random randomGenerator = new Random();
                    List<Peoples> randomPlaceList = new ArrayList<>();
                    for (int i = 0; i < 3; i++) {
                        int randomIndex = randomGenerator.nextInt(placeCount);;
                        Peoples item = randomPlaceList.get(randomIndex);
                        randomPlaceList.add(item);
                    }
                    ListView mListView = findViewById(R.id.place_list);
                    PeoplesAdapter peoplesAdapter = new PeoplesAdapter(getBaseContext(), randomPlaceList);
                    mListView.setAdapter(peoplesAdapter);
                }
            }
        }
    });
}

}

Класс адаптера:

public class PeoplesAdapter extends ArrayAdapter<Peoples> {
public PeoplesAdapter(Context context, List<Peoples> list) {
    super(context, 0, list);
}

@NonNull
@Override
public View getView(int position, View listItemView, @NonNull ViewGroup parent) {
    if (listItemView == null) {
        listItemView = LayoutInflater.from(getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
    }
    Peoples peoples = getItem(position);
    Log.d("TAG", peoples.getName());
    String name = peoples.getName();
    ((TextView) listItemView).setText(name);

    return listItemView;
}
}

И класс модели:

class Peoples {
private String name, age;

public Peoples() {}

public Peoples(String name, String age) {
    this.name = name;
    this.age = age;
}

public String getName() {
    return name;
}

public String getAge() {
    return age;
}
}

База данных Firestore:

Что упускаете, с подключением Firestore и ListView для случайных результатов в выборке?

Какое поведение вы исключили / что происходит? Просто ничего нет? В этом случае вы должны проверить, действительно ли l_check1 возвращает true.

hannojg 08.05.2018 01:32

Я отредактировал вопрос @ Hanno Gödecke В предыдущем упражнении я получил статус putExtra из checkbox, с ним все хорошо. В зависимости от того, какой статус я поставил, я беру query в Firebase. Проблема в подключении адаптера к ListView.

Spike Johnson 08.05.2018 01:47
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
236
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот как вы можете отображать данные из Cloud Firestore в ListView с помощью настраиваемого ArrayAdapter на Android.

Прежде всего, чтобы добавить данные в базу данных, вы должны использовать следующие строки кода:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference placesRef = rootRef.collection("places");
Places places = new Places("PlaceOne", "ImageOne");
placesRef.document().set(places);

Таким образом, вы можете добавить столько мест, сколько захотите. Итак, у вас будет структура базы данных, которая будет выглядеть так:

Firestore-root
   |
   --- places (collection)
         |
         --- placeIdOne (document)
         |      |
         |      --- image: "ImageOne"
         |      |
         |      --- name: "NameOne"
         |
         --- placeIdTwo (document)
         |      |
         |      --- image: "ImageTwo"
         |      |
         |      --- name: "NameTwo"
         |
         --- //And so on

Чтобы быть более понятным, посмотрите изображение ниже:

Если вы хотите запросить данные, вам нужно использовать объект Query.

Query query = placesRef.whereEqualTo("name", "NameOne");

Но поскольку у меня всего несколько записей в базе данных, я буду использовать только placesRef CollectionReference.

Предположим, у вас уже есть ListView в вашем .XML-файле, который выглядит следующим образом:

<ListView
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:id = "@+id/place_list"/>

Чтобы отобразить данные, сначала нужно создать класс адаптера. Этот класс должен выглядеть так:

public class PlacesAdapter extends ArrayAdapter<Places> {
    public PlacesAdapter(Context context, List<Places> list) {
        super(context, 0, list);
    }

    @NonNull
    @Override
    public View getView(int position, View listItemView, @NonNull ViewGroup parent) {
        if (listItemView == null) {
            listItemView = LayoutInflater.from(getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
        }

        Places places = getItem(position);

        String name = places.getName();
        ((TextView) listItemView).setText(name);

        return listItemView;
    }
}

Затем в вашем методе onCreate() используйте следующий код:

ListView mListView = (ListView) findViewById(R.id.place_list);
PlacesAdapter placesAdapter = new PlacesAdapter(getApplicationContext(), randomPlaceList);
mListView.setAdapter(placesAdapter);

И сразу после этого получить данные и уведомить адаптер об изменениях:

placesRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
            List<Places> placesList = new ArrayList<>();
            for (DocumentSnapshot document : task.getResult()) {
                Places places = document.toObject(Places.class);
                placesList.add(places);
            }

            int placeCount = placesList.size();
            Random randomGenerator = new Random();
            List<Places> randomPlaceList = new ArrayList<>();
            for (int i = 1; i <= 3; i++) {
                randomPlaceList.add(placesList.get(randomGenerator.nextInt(placeCount)));
            }
            placesAdapter.notifyDataSetChanged();
        }
    }
});

Результатом в вашем ListView будет 3 случайных места при каждом запуске приложения.

Я знаю, что @Alex Mamo, мне это понравилось, но в нижней части метода onComlete, где я создаю mListAdapter, у меня есть ошибка в конструкторе ArrayAdapter в круглых скобках (this, randomPlaceList). Конструктор с контекстом, не может быть применен к конструктору с QuerySnapshoot

Spike Johnson 08.05.2018 09:51

Прошу вашей помощи в течение 5 дней, не могли бы вы потратить 5 минут за эти 5 дней и написать мне ответ?

Spike Johnson 08.05.2018 10:10

Вообще говоря, здесь, на stackoverflow.com, никто не сделает вашу домашнюю работу / проект за вас. Как видите, вы 3 раза пытались добавить одни и те же вопросы, но никто, кроме меня, не ответил. Обратите внимание, что этот сайт невероятно неэффективен, когда дело доходит до интерактивной отладки. Но на этот раз я напишу код за вас.

Alex Mamo 08.05.2018 11:26

Я вас понимаю, и я не ребенок, я понимаю, где я, и что вы можете просто оставить и проигнорировать мою просьбу. Но ты единственный человек, который мне помогает и не в первый раз. И я вам за это очень благодарен. Я просто так начинаю, и мой первый проект очень важен для меня, и эта проблема - последняя, ​​которую я не могу решить самостоятельно. В любом случае, это не твои проблемы, но в этот раз я все еще рассчитываю на тебя.

Spike Johnson 08.05.2018 11:34

Хорошо, я сейчас напишу код, а когда закончу, оставлю комментарий.

Alex Mamo 08.05.2018 11:37

Спасибо @Alex Mamo, только в прошлый раз, помогите мне изменить рабочий RecycleView на рабочий ListView с моими 3 случайными записями и как применить ваш метод к 13500 моим запросам, кроме того, что я знаю, просто добавьте к каждому запросу. Это несложно, но боюсь, что код будет больше 64 бит и не скомпилируется. И я больше никогда не перекладываю на тебя свои проблемы ..

Spike Johnson 08.05.2018 11:45

Только что проверил, все нормально @ Alex Mamo Огромное спасибо !!!!! Одна проблема заключалась в том, что все элементы в ListView были белыми, но я изменил метод onCreate с getApplicationContext на getBaseContext, и это помогло. Просто хочу сказать, если я применяю этот .addOnCompleteListener к объекту query без каких-либо условий, а затем из OnCreate или внутри, я использую свой цикл if с условиями проверки 500 различных queries, применим ли этот метод к каждому из них?

Spike Johnson 08.05.2018 23:20

Рад слышать, что наконец-то это сработало! Добро пожаловать, @SpikeJohnson. Наверное, да, если правильно его использовать. Если вы считаете, что мой ответ вам помог, примите его и проголосуйте за. Также рассмотрите возможность принятия этот ответ и проголосуйте за. Спасибо!

Alex Mamo 08.05.2018 23:26

Еще раз спасибо @Alex Mamo. Ты действительно спас меня и дал новое вдохновение!

Spike Johnson 08.05.2018 23:38

Ваше здоровье! @SpikeJohnson

Alex Mamo 08.05.2018 23:40

Привет, @Alex Mamo, это снова я. Мой проект уже был в порядке, но сегодня я запустил его и получил эту ошибку: Process: com.example.eugene.lafinalproduction, PID: 9741 java.lang.IllegalArgumentException: n <= 0: 0 в java.util.Random.nextInt (Random.java:182) в com.example.eugene.lafinalproduction.ListViewPlaces $ 1.onComp‌ lete (ListViewPlaces.‌ java: 63) в этой строке: randomPlaceList.add (placesList.get (randomGenerator.nextInt (p‌ laceCount ))); что это такое? сегодня утром все было хорошо, я просто перезагружаю компьютер, и эта катастрофа

Spike Johnson 11.05.2018 17:42

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

Alex Mamo 13.05.2018 09:56

Понятно! @Alex Mamo

Spike Johnson 13.05.2018 10:07

Хорошо понял! Необходимо изменить: Peoples item = randomPlaceList.get (randomIndex); по этому поводу: Peoples item = peopleList.get (randomIndex); Но позже, когда вы помогли мне @Alex Mamo, все тоже было хорошо, просто какие-то невероятные причины, грядет ошибка. Просто волшебство для меня!

Spike Johnson 13.05.2018 10:12

Другие вопросы по теме