如何从Android MVVM体系结构的LiveData列表中获取第一个或(任何)元素? [英] how to get the first or (any) element from a LiveData List in Android MVVM architecture?

查看:492
本文介绍了如何从Android MVVM体系结构的LiveData列表中获取第一个或(任何)元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用MVVM架构构建了一个带有Repository作为ViewModel和Room数据库之间中介的Android应用程序.在其中一个函数中,我从存储库类中的表中检索对象列表,以便可以从ViewModel类中调用它.

I used MVVM architecture to build an Android application with a Repository as a mediation between the ViewModel and Room database. In one of the functions, I retrieve a list of objects from a table in the repository class so that I can call it from the ViewModel class.

如何从存储库类中检索列表中的第一个元素,而不是在任何一项活动中观察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(名字",mAllStudent.get(0)); //我想在日志中输入学生姓名,而无需在其中添加函数 viewModel并在任何活动中观察到

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;
}

}

推荐答案

如何从Android中的LiveData列表中获取第一个或(任何)元素 MVVM体系结构

how to get the first or (any) element from a LiveData List in Android MVVM architecture

如果要从LiveData列表中获取特定元素,则需要使用偏移量限制查询.

If you want to get a particular element from a LiveData list, then you need to limit your query with an offset.

默认情况下,限制查询不会考虑该查询的偏移量;因此默认偏移值为0.

By default limiting a query doesn't consider an offset to it; so the default offset value is 0.

例如,在您的Dao中:

例1和示例2的以下查询2是等效的,因为默认偏移值为0.

The below queries of Example 1 & 2 are equivalent, because the default offset value is 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

Note: Here I am assuming your model class is Student

这是关于第一行;但要返回行号 x ,则需要将偏移量设置为: x-1 ,因为偏移量是基于0的值

This is about the first row; but to return row number x then you need to manipulate the offset to be: x-1, as the offset is 0-based value

示例3(与示例2相同的Dao查询)

getStudents(1, 1); // returns the second row
getStudents(1, 4); // returns the fifth row

如果要返回多个行,则需要操纵LIMIT值,因此要从结果中返回 x 行,然后将查询限制为 x .

If you want to return more than one row, then you need to manipulate the LIMIT value, so to return x rows from the results, then limit the query with 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中以获取列表或列表中的任何元素 列表).我需要的是在输入的同时键入列表中的第一个值 使用存储库类中的函数. –

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. –

现在您正在使用以下查询

Now you are using below query

@Query("SELECT * FROM students")
LiveData<List<Student>> getStudents();

您要:

  1. 获取列表中的第一个或任何元素.并按照 上面提到的
  2. 通过所有步骤(以在ViewModel类中定义此方法 并在MainActivity中观察它以获取列表或任何其他内容 列表中的元素).
  1. Get the first or any element in the list. and to do so according to what is mentioned above
  2. 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).

要这样做:

在道中:将查询更改为

@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中观察到?我的问题不是全部 步骤.

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推荐的模型,您可以从Dao查询而不是LiveData<List<Student>>返回List<Student>,但是坏消息是:

Yes it's possible, but the above model is the recommended model by Google, You can return a List<Student> from Dao query instead of LiveData<List<Student>>, but the bad news are:

  1. 您必须在单独的后台线程中处理该问题;因为 LiveData免费这样做.
  2. 您将失去LiveData的价值;所以你必须手动 刷新列表以检查是否有更新,因为您将无法使用观察者模式.
  1. You have to handle that in a separate background thread; because the LiveData do that for free.
  2. You will lose the value of the LiveData; so you have to manually refresh the list to check any update as you won't be able to use the observer pattern.

因此,您可以省略ViewModelRepository,并按照以下步骤执行活动中的所有工作:

So, you can omit using ViewModel and Repository, and do all the stuff from the activity as follows:

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);

然后查询Dao:

@Query("SELECT * FROM students LIMIT  :limit OFFSET :offset")
List<Student> getAllStudents(int limit, int offset);

这篇关于如何从Android MVVM体系结构的LiveData列表中获取第一个或(任何)元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆