ListView не получает уведомление при изменении данных даже при вызове notifyDataSetChanged () - PullRequest
1 голос
/ 14 июля 2020

Я создал приложение android, которое может обновлять мою базу данных firebase. Мне удалось подключить базу данных к моему приложению, получить данные, отредактировать их и сохранить. Однако в некоторых случаях приложение вылетает из-за следующей ошибки:

Process: com.example.codelibadministrator, PID: 1883
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131230830, class android.widget.ListView) with Adapter(class android.widget.ArrayAdapter)]

Я провел некоторое исследование, и большинство решений, с которыми я столкнулся, заявляют, что мне нужно вызвать метод notifyDataSetChanged (), который Я делаю это, но ошибка все равно возникает.

Я отображаю информацию из базы данных в виде списка, который находится во фрагменте. Щелчок по одному из элементов в представлении списка запустит новое действие, в котором информацию об этом конкретном элементе можно будет изменить или удалить. После того, как изменения внесены (или не сделаны) или определенный элемент удален, приложение возвращается к фрагменту с представлением списка, вызывает метод notifyDataSetChanged () и обновляет представление списка. В чем проблема с моим кодом?

Ниже приводится метод, отвечающий за выборку данных из базы данных и обновление списка с полученными данными. Он вызывается, когда создается фрагмент и когда приложение возвращается из активности, ответственной за редактирование данных.

private void fetchAndDisplayData() {

     list.clear();
     idList.clear();

     ref.addValueEventListener(new ValueEventListener() {
         // fetch data from database
         @Override
         public void onDataChange(@NonNull final DataSnapshot dataSnapshot) {
             for (DataSnapshot ds : dataSnapshot.getChildren()) {

                 books = ds.getValue(Book.class);
                 String book = books.getTitle();
                 String bookId = books.getPostId();
                 boolean isDuplicate = false;

                 for (int i = 0 ; i < list.size(); i++) {
                     if (list.get(i) == book) {
                         isDuplicate = true;
                     }
                 }
                 if (!isDuplicate) {
                     list.add(book);
                     idList.add(bookId);
                 }

                 /*idList.add(books.getPostId());*/
             }

             listView.setAdapter(adapter);

         }


         @Override
         public void onCancelled(@NonNull DatabaseError databaseError) {

         }
     });
 }

Мой метод результата действия, который вызывается, когда действие, ответственное за редактирование информации для отдельного элемента отделка. Мой метод onDataSetChanged () вызывается здесь перед заполнением списка обновленных данных.

@Override
 public void onActivityResult(int requestCode, int resultCode, Intent data) {
     super.onActivityResult(requestCode, resultCode, data);

     if (requestCode == DATA_CHANGED && resultCode == Activity.RESULT_OK) {
            listView.setAdapter(null);
            adapter.notifyDataSetChanged();
            fetchAndDisplayData();
     }
 }

РЕДАКТИРОВАТЬ: ошибка, похоже, возникает, когда осуществляется доступ к элементу, а информация об элементе не изменяется. Действие завершится sh и вернется к представлению списка, когда я снова попытаюсь получить доступ к тому же элементу или другому элементу, я получаю сообщение об ошибке.

EDIT2: После некоторой отладки я заметил, что часть onActivityResult моего кода никогда не выполняется. Возможно, поэтому у меня возникла проблема. Возможно ли, что этот код никогда не выполняется, потому что я начинаю новое действие из фрагмента?

EDIT3: Итак, я нашел проблему моего вопроса. К методу onActivityResult во фрагменте никогда не осуществляется доступ, потому что, когда второе действие возвращает свой результат, он возвращает его методу onActivityResult объекта MainActivity, где находится фрагмент, вызывающий второе действие. Теперь ответ на мою проблему смещается на «Как я могу отправить информацию из метода onActivityResult () основного действия в onActivityResult () фрагмента в том же действии?»

Ответы [ 2 ]

1 голос
/ 14 июля 2020
(YourActivity.this).runOnUiThread(new Runnable() {
    @Override
    public void run() {
        listView.setAdapter(adapter)
    }
});
0 голосов
/ 15 июля 2020

Как видно, метод notifyDataSetChanged () никогда не вызывался, потому что к методу onActivityResult () фрагмента никогда не обращались. Это произошло потому, что я начинал операцию редактирования из фрагмента следующим образом:

getActivity().startActivityForResult(intent, DATA_CHANGED, null);

Это привело к тому, что программа обратилась к методу onActivityResult () основного действия, которое отвечает за фрагменты, а не за onActivityResult () фрагмента.

Изменение метода startActivityForResult () на следующее решило проблему:

startActivityForResult(intent, DATA_CHANGED, null);
...