cara mendapatkan elemen pertama atau (apa saja) dari Daftar LiveData di arsitektur AndroidMVVM
Jika Anda ingin mendapatkan elemen tertentu dari daftar LiveData, Anda perlu membatasi kueri Anda dengan offset.
Secara default, membatasi kueri tidak mempertimbangkan offset; jadi nilai offset default adalah 0.
Misalnya, di Dao
. Anda :
Kueri Contoh 1 &2 di bawah ini setara, karena nilai offset default adalah 0.
Contoh
@Query("SELECT * FROM students LIMIT :limit")
LiveData<List<Student>> getStudents(int limit);
// Query
getStudents(1); // returns the first row of the list
Contoh 2
@Query("SELECT * FROM students LIMIT :limit OFFSET :offset")
LiveData<List<Student>> getStudents(int limit, int offset);
// Query
getStudents(1, 0); // returns the first row of the list
Catatan: Di sini saya mengasumsikan kelas model Anda adalah Student
Ini tentang baris pertama; tetapi untuk mengembalikan nomor baris x
maka Anda perlu memanipulasi offset menjadi:x-1
, karena offsetnya adalah nilai berbasis 0
Contoh 3 (Kueri Dao Sama dengan Contoh 2)
getStudents(1, 1); // returns the second row
getStudents(1, 4); // returns the fifth row
Jika Anda ingin mengembalikan lebih dari satu baris, maka Anda perlu memanipulasi LIMIT
nilai, jadi untuk mengembalikan x
baris dari hasil, lalu batasi kueri dengan x
.
getStudents(2, 1); // returns the second and third rows
getStudents(3, 4); // returns the fifth, sixth, and seventh rows
Semoga ini menjawab pertanyaan Anda
Edit sesuai komentar
Saya sudah memiliki daftar yang dikembalikan oleh kueri lain
@Query("SELECT * FROM
students)
LiveData<List<Student>> getStudents();
Jadi nilai yang dikembalikan adalah daftar. Saya ingin mendapatkan elemen pertama dari daftar. Jawaban ini benar-benar mengembalikan elemen pertama, tetapi saya harus melewati semua langkah (untuk mendefinisikan metode ini diViewModel
kelas dan amati diMainActivity
untuk mendapatkan daftar atau elemen apa pun dalam daftar). Yang saya butuhkan adalah mengetikkan nilai pertama dalam daftar saat saya menggunakan fungsi di kelas repositori. –
Sekarang Anda menggunakan kueri di bawah
@Query("SELECT * FROM students")
LiveData<List<Student>> getStudents();
Dan Anda ingin:
- Dapatkan elemen pertama atau elemen apa pun dalam daftar. dan melakukannya sesuai dengan apa yang disebutkan di atas
- Lewati semua langkah (untuk menentukan metode ini di
ViewModel
classdan amati diMainActivity
untuk mendapatkan daftar atau elemen apa pun dalam daftar).
Jadi untuk melakukan itu:
Dalam Dao: :Ubah kueri Anda menjadi
@Query("SELECT * FROM students LIMIT :limit OFFSET :offset")
LiveData<List<Student>> getAllStudents(int limit, int offset);
Dalam Repositori:
public class StudentRepository {
...
public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
return mDAO.getAllStudents(limit, offset);
}
}
Dalam ViewModel:
public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
return mRepository.getAllStudents(limit, offset);
}
Dalam Aktivitas:
private void getAllStudents(int limit, int offset) {
mViewModel.getAllStudents(limit, offset).observe(this, new Observer<List<Student>>() {
@Override
public void onChanged(List<Student> students) {
if (students != null) {
// Here you can set RecyclerView list with `students` or do whatever you want
}
}
});
}
Dan untuk mengujinya:
getAllStudents(1, 0); // return first row from the table.
getAllStudents(2, 0); // return first 2 rows from the table.
getAllStudents(2, 1); // return 2nd and 3rd rows from the table.
getAllStudents(-1, 5); // remove first 5 rows from the table.
Dan untuk mengembalikan elemen pertama dalam daftar mAllStudents untuk mengetikkan nama siswa pertama di Log.d
Jadi, Dalam Aktivitas Anda
mViewModel.getAllStudents(1, 0).observe(this, new Observer<List<Student>>() {
@Override
public void onChanged(List<Student> students) {
if (students != null) {
Student student = students.get(0);
Log.d("First_Name", student.getName());
}
}
});
Sunting, apakah mungkin mengembalikan elemen apa pun dari daftar tanpa mengikuti semua langkah seperti menulis fungsi di ViewModeland, mengamatinya di MainActivity? Pertanyaan saya adalah untuk tidak mengikuti semua langkah.
Ya itu mungkin, tetapi model di atas adalah model yang direkomendasikan oleh Google, Anda dapat mengembalikan List<Student>
dari Dao
kueri alih-alih LiveData<List<Student>>
, tapi kabar buruknya adalah:
- Anda harus menanganinya di utas latar belakang yang terpisah; karena
LiveData
lakukan itu secara gratis. - Anda akan kehilangan nilai
LiveData
; jadi Anda harus menyegarkan daftar secara manual untuk memeriksa pembaruan apa pun karena Anda tidak akan dapat menggunakan pola pengamat.
Jadi, Anda dapat menghilangkan menggunakan ViewModel
dan Repository
, dan lakukan semua hal dari aktivitas sebagai berikut:
private Executor mExecutor = Executors.newSingleThreadExecutor();
public void getAllStudents(final int limit, final int offset) {
final StudentDAO mDAO = StudentDatabase.getInstance(getApplicationContext()).getStudentDAO();
mExecutor.execute(new Runnable() {
@Override
public void run() {
List<Student> students = mDAO.getAllStudents(limit, offset);
Student student = students.get(0);
Log.d("First_Name", student.getName());
}
});
}
// Usage: getAllStudents(1, 0);
Dan kueri untuk Dao:
@Query("SELECT * FROM students LIMIT :limit OFFSET :offset")
List<Student> getAllStudents(int limit, int offset);