如何从 Android 中的 LiveData 列表中获取第一个或(任何)元素
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 相同的 Dao 查询)
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
希望这能解决您的问题
根据 cmets 编辑
我已经有另一个查询返回的列表@Query("SELECT * FROM
students) LiveData<List<Student>> getStudents(); 所以返回值
是一个列表。我想从列表中获取第一个元素。
这个答案真正返回第一个元素,但我需要通过所有
步骤(在ViewModel 类中定义此方法并观察它
在MainActivity 中以获取列表或任何元素
列表)。我需要的是在我输入列表中的第一个值
使用存储库类中的函数。 ——
现在您正在使用以下查询
@Query("SELECT * FROM students")
LiveData<List<Student>> getStudents();
你想:
- 获取列表中的第一个或任何元素。并根据
上面提到的
- 通过所有步骤(在
ViewModel类中定义这个方法
并在MainActivity 中观察它以获取列表或任何
列表中的元素)。
所以这样做:
In Dao::将查询更改为
@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());
}
}
});
编辑是否可以返回列表中的任何元素而不
遵循所有步骤,例如在 ViewModel 中编写函数
并在 MainActivity 中观察?我的问题是不要跟随所有
步骤。
是的,这是可能的,但上述模型是 Google 推荐的模型,您可以从 Dao 查询返回 List<Student> 而不是 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);