Saya menggunakan mvp dengan repositori untuk memperbarui item di recyclerview ketika item di database firestore berubah.

Seperti yang ditanyakan, berikut ini beberapa kode lagi dari SharedModelClass:

   public LiveData<List<Task>> tasksListening() {
        return repository.tasksListening(false);
    }

Yang mengarah ke:

   public LiveData<List<Task>> tasksListening(boolean b) {
            return new FirestoreTasksData(tasksReference, b);
    }

Inilah FirestoreTasksData memperluas LiveData:

public class FirestoreTasksData extends LiveData<List<Task>> {

    List<Task> tasks;

         for (QueryDocumentSnapshot doc : value) {
                Task item = doc.toObject(Task.class);
                tasks.add(item);
         }
 
        setValue(tasks);


    };
}

Semua berfungsi sempurna kecuali daftar itu diperbarui secara keseluruhan bahkan ketika memperbarui satu item.

sharedViewModel.tasksListening().observe(getViewLifecycleOwner(), tasks -> {
            tasksAdapter.submitList(tasks);
        });

Dan ini adalah kode adaptor:

    public class MyTasksAdapter extends RecyclerView.Adapter<MyTasksAdapter.TaskHolder> {
    
        private final AsyncListDiffer<Task> mDiffer = new AsyncListDiffer<>(this, DIFF_CALLBACK);
    
        private static final DiffUtil.ItemCallback<Task> DIFF_CALLBACK = new DiffUtil.ItemCallback<Task>() {
            @Override
            public boolean areItemsTheSame(@NonNull Task oldItem, @NonNull Task newItem) {
                return oldItem.getId().equals(newItem.getId());
            }
    
            @Override
            public boolean areContentsTheSame(@NonNull Task oldItem, @NonNull Task newItem) {
                return oldItem.geteDate().equals(newItem.geteDate()) && (new HashSet<>(oldItem.getRoles().values()).equals(new HashSet<>(newItem.getRoles().values())));
            }
        };
    }

public void submitList(List<Task> list) {
          mDiffer.submitList(list);
      }

    @Override
    public int getItemCount() {
        return mDiffer.getCurrentList().size();
    }

Apakah ini bug atau fitur? Saya menggunakan adaptor pendaur ulang UI Firestore sebelumnya, baru saja memutuskan untuk refactor kode.

0
saintPeter 23 Desember 2020, 03:21

3 jawaban

Jawaban Terbaik

Ingin menghapus posting tetapi aturan.

Saya memecahkan masalah. Masalahnya adalah bahwa semua bekerja dengan baik. Jangan ragu untuk menggunakan kode jika diperlukan.

Saya baru menyadari bahwa pengamat di dalam memanggil metode lain, itulah alasan saya melihat efek rendering seolah-olah ada beberapa bug dengan adaptor.

sharedViewModel.tasksListening().observe(getViewLifecycleOwner(), tasks -> {
            tasksAdapter.submitList(tasks);
              checkEmpty(tasks.size());
        });



 private void checkEmpty(int size) {

        if (size == 0) {
            crossFade(noDataLayout, mTasksRecycler);
        } else {
            crossFade(mTasksRecycler, noDataLayout);

        }
    }

Saya memperbaikinya dan sekarang semuanya baik-baik saja.

0
saintPeter 23 Desember 2020, 21:18

Itu adalah perilaku yang diharapkan. Jika ada perubahan pada hasil kueri/koleksi, kode Anda akan dipanggil dengan QuerySnapshot objek dari semua perubahan yang cocok dengan kueri/koleksi.

Jika Anda ingin melihat apa yang telah berubah, Anda dapat melihat getDocumentChanges() snapshot untuk melihatnya. Untuk lebih lanjut tentang ini (dan sebuah contoh) lihat dokumentasi di melihat perubahan antara cuplikan.

1
Frank van Puffelen 23 Desember 2020, 01:41

Daripada menerapkan adaptor khusus dan DiffUtil Callback.

Lihat LiveAdapter.

Anda hanya perlu menambahkan dependensi terbaru di Gradle.

dependencies {
    implementation 'com.github.RaviKoradiya:LiveAdapter:1.3.2-1608532016'
    // kapt 'com.android.databinding:compiler:GRADLE_PLUGIN_VERSION' // this line only for Kotlin projects
}

Dan ikat adaptor dengan RecyclerView Anda

LiveAdapter(
            data = liveListOfItems,
            lifecycleOwner = this@MainActivity,
            variable = BR.item )
            .map<Header, ItemHeaderBinding>(R.layout.item_header) {
                areContentsTheSame { old: Header, new: Header ->
                    return@areContentsTheSame old.text == new.text
                }
            }
            .map<Point, ItemPointBinding>(R.layout.item_point) {
                areContentsTheSame { old: Point, new: Point ->
                    return@areContentsTheSame old.id == new.id
                }
            }
            .into(recyclerview)

Itu dia. Tidak perlu menulis kode tambahan untuk implementasi adaptor, amati LiveData dan beri tahu adaptor.

0
RBK 23 Desember 2020, 07:54