как да получите първия или (който и да е) елемент от списък на LiveData в архитектура на AndroidMVVM
Ако искате да получите конкретен елемент от списък LiveData, тогава трябва да ограничите заявката си с отместване.
По подразбиране ограничаването на заявка не отчита отместване към нея; така че стойността на отместване по подразбиране е 0.
Например във вашия Dao
:
Заявките по-долу от Примери 1 и 2 са еквивалентни, тъй като стойността на отместване по подразбиране е 0.
Пример
@Query("SELECT * FROM students LIMIT :limit")
LiveData<List<Student>> getStudents(int limit);
// Query
getStudents(1); // returns the first row of the list
Пример 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
Забележка: Тук предполагам, че вашият моделен клас е Student
Това е за първия ред; но да върне номер на ред x
след това трябва да манипулирате отместването да бъде:x-1
, тъй като отместването е базирана на 0 стойност
Пример 3 (същата Dao заявка като пример 2)
getStudents(1, 1); // returns the second row
getStudents(1, 4); // returns the fifth row
Ако искате да върнете повече от един ред, тогава трябва да манипулирате LIMIT
стойност, така че да върне x
редове от резултатите, след което ограничете заявката с x
.
getStudents(2, 1); // returns the second and third rows
getStudents(3, 4); // returns the fifth, sixth, and seventh rows
Надяваме се, че това отговаря на въпроса ви
Редактиране според коментарите
Вече имам списък, върнат от друга заявка
@Query("SELECT * FROM
students)
LiveData<List<Student>> getStudents();
Така че върнатата стойност е списък. Искам да получа първия елемент от списъка. Този отговор наистина връща първия елемент, но трябва да премина всички стъпки (за да дефинирам този метод вViewModel
клас и го наблюдавайте вMainActivity
за да получите списъка или който и да е елемент в списъка). Това, което ми трябва, е да напиша първата стойност в списъка, докато забавлявам функцията в класа на хранилището. –
Сега използвате заявката по-долу
@Query("SELECT * FROM students")
LiveData<List<Student>> getStudents();
И искате да:
- Вземете първия или който и да е елемент от списъка. и да го направи според гореспоменатото
- Преминете всички стъпки (за да дефинирате този метод в
ViewModel
). клас и го наблюдавайте вMainActivity
за да получите списъка или който и да е елемент от списъка).
Така че, за да направите това:
На дао: :Променете заявката си на
@Query("SELECT * FROM students LIMIT :limit OFFSET :offset")
LiveData<List<Student>> getAllStudents(int limit, int offset);
В хранилище:
public class StudentRepository {
...
public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
return mDAO.getAllStudents(limit, offset);
}
}
В ViewModel:
public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
return mRepository.getAllStudents(limit, offset);
}
В активност:
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
}
}
});
}
И за да тествате това:
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.
И да върне първия елемент в списъка mAllStudents, за да въведете името на първия ученик в Log.d
И така, във вашата дейност
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());
}
}
});
Редактиране възможно ли е да се върне който и да е елемент от списъка, без да се следват всички стъпки, като например писане на функция във ViewMode и наблюдавайте това в MainActivity? Въпросът ми е да не следвате всички стъпки.
Да, възможно е, но горният модел е препоръчан модел от Google. Можете да върнете List<Student>
от Dao
заявка вместо LiveData<List<Student>>
, но лошите новини са:
- Трябва да се справите с това в отделна фонова нишка; защото
LiveData
направете това безплатно. - Ще загубите стойността на
LiveData
; така че трябва ръчно да опресните списъка, за да проверите всяка актуализация, тъй като няма да можете да използвате модела на наблюдателя.
Така че можете да пропуснете използването на ViewModel
и Repository
, и направете всички неща от дейността, както следва:
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);
И заявката за Дао:
@Query("SELECT * FROM students LIMIT :limit OFFSET :offset")
List<Student> getAllStudents(int limit, int offset);