如何从 Android MVVM 架构中的 LiveData 列表中获取第一个或(任何)元素?
how to get the first or (any) element from a LiveData List in Android MVVM architecture?
我使用 MVVM 架构构建了一个 Android 应用程序,其中包含一个存储库作为 ViewModel
和 Room 数据库之间的中介。在其中一个函数中,我从存储库 class 中的 table 中检索了一个对象列表,以便我可以从 ViewModel
class.[=15= 中调用它]
如何从存储库 class 中检索列表中的第一个元素,而不是在任何一个活动中观察 LiveData
?
这是我的存储库 class:
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));
// I want to type the student name in the Log without adding a function in
the viewModel and observe that in any Activity**
return mAllStudents;
}
}
how to get the first or (any) element from a LiveData List in Android
MVVM architecture
如果您想从 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
注:这里我假设你的模型class是Student
这是第一行;但是对于 return 行号 x
那么您需要将偏移量操作为:x-1
,因为偏移量是基于 0 的值
示例 3(与示例 2 相同的 Dao 查询)
getStudents(1, 1); // returns the second row
getStudents(1, 4); // returns the fifth row
如果你想return超过一行,那么你需要操作LIMIT
值,所以要returnx
行,然后用 x
.
限制查询
getStudents(2, 1); // returns the second and third rows
getStudents(3, 4); // returns the fifth, sixth, and seventh rows
希望这能解决您的问题
Edit as per comments
I already have a list returned by another query @Query("SELECT * FROM
students)
LiveData<List<Student>> getStudents();
So the returned value
is a list. I want to get the first element from the list.
This answer returns the first element truly, but I need to pass all
the steps (to define this method in the ViewModel
class and observe it
in the MainActivity
in order to get the list or any element in the
list). What I need is to type the first value in the list while I am
using the function in the repository class. –
现在您正在使用以下查询
@Query("SELECT * FROM students")
LiveData<List<Student>> getStudents();
你想要:
- 获取列表中的第一个或任何元素。并根据
上面提到的
- 通过所有步骤(在
ViewModel
class 中定义此方法
并在 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);
}
在Activity中:
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.
并以return mAllStudents 列表中的第一个元素为输入第一个学生姓名的Log.d
所以,在你的 Activity
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());
}
}
});
Edit is it possible to return any element of the list without
following all the steps such as writing a function in the ViewModel
and observe that in the MainActivity? My question is not to follow all
the steps.
可以,但是上面的模型是Google推荐的模型,你可以return一个List<Student>
来自Dao
查询而不是LiveData<List<Student>>
,但坏消息是:
- 你必须在单独的后台线程中处理它;因为
LiveData
免费做。
- 你将失去
LiveData
的价值;所以你必须手动
刷新列表以检查任何更新,因为您将无法使用观察者模式。
因此,您可以省略使用 ViewModel
和 Repository
,并按如下方式执行 activity 中的所有内容:
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);
我使用 MVVM 架构构建了一个 Android 应用程序,其中包含一个存储库作为 ViewModel
和 Room 数据库之间的中介。在其中一个函数中,我从存储库 class 中的 table 中检索了一个对象列表,以便我可以从 ViewModel
class.[=15= 中调用它]
如何从存储库 class 中检索列表中的第一个元素,而不是在任何一个活动中观察 LiveData
?
这是我的存储库 class:
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));
// I want to type the student name in the Log without adding a function in
the viewModel and observe that in any Activity**
return mAllStudents;
}
}
how to get the first or (any) element from a LiveData List in Android MVVM architecture
如果您想从 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
注:这里我假设你的模型class是Student
这是第一行;但是对于 return 行号 x
那么您需要将偏移量操作为:x-1
,因为偏移量是基于 0 的值
示例 3(与示例 2 相同的 Dao 查询)
getStudents(1, 1); // returns the second row
getStudents(1, 4); // returns the fifth row
如果你想return超过一行,那么你需要操作LIMIT
值,所以要returnx
行,然后用 x
.
getStudents(2, 1); // returns the second and third rows
getStudents(3, 4); // returns the fifth, sixth, and seventh rows
希望这能解决您的问题
Edit as per comments
I already have a list returned by another query
@Query("SELECT * FROM
students)
LiveData<List<Student>> getStudents();
So the returned value is a list. I want to get the first element from the list. This answer returns the first element truly, but I need to pass all the steps (to define this method in theViewModel
class and observe it in theMainActivity
in order to get the list or any element in the list). What I need is to type the first value in the list while I am using the function in the repository class. –
现在您正在使用以下查询
@Query("SELECT * FROM students")
LiveData<List<Student>> getStudents();
你想要:
- 获取列表中的第一个或任何元素。并根据 上面提到的
- 通过所有步骤(在
ViewModel
class 中定义此方法 并在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);
}
在Activity中:
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.
并以return mAllStudents 列表中的第一个元素为输入第一个学生姓名的Log.d
所以,在你的 Activity
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());
}
}
});
Edit is it possible to return any element of the list without following all the steps such as writing a function in the ViewModel and observe that in the MainActivity? My question is not to follow all the steps.
可以,但是上面的模型是Google推荐的模型,你可以return一个List<Student>
来自Dao
查询而不是LiveData<List<Student>>
,但坏消息是:
- 你必须在单独的后台线程中处理它;因为
LiveData
免费做。 - 你将失去
LiveData
的价值;所以你必须手动 刷新列表以检查任何更新,因为您将无法使用观察者模式。
因此,您可以省略使用 ViewModel
和 Repository
,并按如下方式执行 activity 中的所有内容:
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);