jak pobrać pierwszy lub (dowolny) element z listy LiveData w architekturze AndroidMVVM
Jeśli chcesz pobrać konkretny element z listy LiveData, musisz ograniczyć zapytanie za pomocą przesunięcia.
Domyślnie ograniczenie zapytania nie uwzględnia przesunięcia do niego; więc domyślna wartość przesunięcia to 0.
Na przykład w swoim Dao
:
Poniższe zapytania z Przykładu 1 i 2 są równoważne, ponieważ domyślna wartość przesunięcia to 0.
Przykład
@Query("SELECT * FROM students LIMIT :limit")
LiveData<List<Student>> getStudents(int limit);
// Query
getStudents(1); // returns the first row of the list
Przykład 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
Uwaga: Tutaj zakładam, że twoja klasa modelu to Student
Chodzi o pierwszy rząd; ale aby zwrócić numer wiersza x
następnie musisz zmienić przesunięcie tak, aby było:x-1
, ponieważ przesunięcie jest wartością od 0
Przykład 3 (to samo zapytanie Dao co w przykładzie 2)
getStudents(1, 1); // returns the second row
getStudents(1, 4); // returns the fifth row
Jeśli chcesz zwrócić więcej niż jeden wiersz, musisz manipulować LIMIT
wartość, aby zwrócić x
wierszy z wyników, a następnie ogranicz zapytanie za pomocą x
.
getStudents(2, 1); // returns the second and third rows
getStudents(3, 4); // returns the fifth, sixth, and seventh rows
Mam nadzieję, że to rozwiąże Twoje pytanie
Edytuj zgodnie z komentarzami
Mam już listę zwróconą przez inne zapytanie @Query("SELECT * FROM
students)
LiveData<List<Student>> getStudents();
Zwrócona wartość to lista. Chcę uzyskać pierwszy element z listy. Ta odpowiedź zwraca naprawdę pierwszy element, ale muszę przejść wszystkie kroki (aby zdefiniować tę metodę w ViewModel
i obserwuj ją w MainActivity
w celu pobrania listy lub dowolnego elementu na liście). To, czego potrzebuję, to wpisać pierwszą wartość na liście, gdy bawię się funkcją w klasie repozytorium. –
Teraz używasz poniższego zapytania
@Query("SELECT * FROM students")
LiveData<List<Student>> getStudents();
I chcesz:
- Pobierz pierwszy lub dowolny element z listy. i zrobić to zgodnie z tym, co wspomniano powyżej
- Przejdź wszystkie kroki (aby zdefiniować tę metodę w
ViewModel
classi obserwuj to wMainActivity
aby uzyskać listę lub dowolny element z listy).
Aby to zrobić:
W Dao: :Zmień zapytanie na
@Query("SELECT * FROM students LIMIT :limit OFFSET :offset")
LiveData<List<Student>> getAllStudents(int limit, int offset);
W repozytorium:
public class StudentRepository {
...
public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
return mDAO.getAllStudents(limit, offset);
}
}
W ViewModelu:
public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
return mRepository.getAllStudents(limit, offset);
}
Aktywność:
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
}
}
});
}
Aby to przetestować:
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.
I zwrócić pierwszy element z listy mAllStudents w celu wpisania pierwszego nazwiska ucznia w Log.d
Tak więc w Twojej aktywności
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());
}
}
});
Edytuj czy można zwrócić dowolny element listy bez wykonywania wszystkich kroków, takich jak pisanie funkcji w ViewModeland zauważ, że w MainActivity? Moje pytanie nie dotyczy wszystkich kroków.
Tak, jest to możliwe, ale powyższy model jest rekomendowanym modelem przez Google. Możesz zwrócić List<Student>
z Dao
zapytanie zamiast LiveData<List<Student>>
, ale złe wieści to:
- Musisz sobie z tym poradzić w osobnym wątku w tle; ponieważ
LiveData
zrób to za darmo. - Stracisz wartość
LiveData
; więc musisz ręcznie odświeżyć listę, aby sprawdzić jakąkolwiek aktualizację, ponieważ nie będziesz mógł użyć wzorca obserwatora.
Możesz więc pominąć za pomocą ViewModel
i Repository
i wykonaj wszystkie czynności z ćwiczenia w następujący sposób:
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);
I zapytanie o Dao:
@Query("SELECT * FROM students LIMIT :limit OFFSET :offset")
List<Student> getAllStudents(int limit, int offset);