как получить первый или (любой) элемент из списка LiveData в Android архитектура MVVM
Если вы хотите получить определенный элемент из списка 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 (тот же запрос Дао, что и в Примере 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
, чтобы получить список или любой элемент в list).
Для этого:
In Dao: : измените свой запрос на
@Query("SELECT * FROM students LIMIT :limit OFFSET :offset")
LiveData<List<Student>> getAllStudents(int limit, int offset);
In Репозиторий:
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());
}
}
});
Редактировать можно ли вернуть любой элемент списка без выполнения всех шагов, таких как написание функции в ViewModel, и наблюдать это в MainActivity? У меня вопрос не в том, чтобы выполнить все шаги.
Да, это возможно, но приведенная выше модель является рекомендованной моделью Google. Вы можете вернуть List<Student>
из Dao
запроса вместо LiveData<List<Student>>
, но плохие новости:
- Вы должны обрабатывать это в отдельном фоновом потоке; потому что
LiveData
делает это бесплатно. - Вы потеряете значение
LiveData
; поэтому вам нужно вручную обновить список sh, чтобы проверить любое обновление, так как вы не сможете использовать шаблон наблюдателя.
Итак, вы можете опустить 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);