我使用MVVM架构来构建一个Android应用程序,该存储库作为ViewModel和Room数据库之间的中介。在其中一个函数中,我从存储库类中的表中检索对象列表,以便可以从ViewModel类中调用它。
如何从存储库类中检索列表中的第一个元素,而不是观察任何活动中的LiveData?
这是我的存储库类:
public class StudentRepository {
private StudentDAO mStudentDAO;
private LiveData<List<Student>> mAllStudents;
public StudentRepository(Application application){
StudentRoomDatabase db = StudentRoomDatabase.getDatabase(application);
mStudentDAO= db.StudentDAO();
mAllStudents= mStudentDAO.getAllStudents();
}
public LiveData<List<Word>> getAllStudents(){
// What I need to return the first element in the mAllStudents list
// in order to type the first student name in the Log.d
Log.d(“ First_Name”,mAllStudent.get(0));//我想在日志中输入学生姓名,而无需在其中添加函数viewModel并在任何Activity中观察它
return mAllStudents;
}
}
如何从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
希望这能解决您的问题
根据评论编辑
我已经有另一个查询
@Query("SELECT * FROM
返回的列表students)
LiveData<List<Student>> getStudents();
所以返回值是一个列表。我想从列表中获取第一个元素。这个答案确实返回了第一个元素,但我需要通过所有步骤(在ViewModel
类中定义此方法并观察它在MainActivity
中获取列表或列表中的任何元素清单)。我需要的是在输入的同时键入列表中的第一个值使用存储库类中的函数。 –
现在您正在使用以下查询
@Query("SELECT * FROM students")
LiveData<List<Student>> getStudents();
并且您想:
ViewModel
类中定义此方法并在MainActivity
中观察它以获取列表或任何列表中的元素)。这样做:
在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());
}
}
});