AndroidMVVMアーキテクチャのLiveDataリストから最初の要素または(任意の)要素を取得する方法
LiveDataリストから特定の要素を取得する場合は、クエリをオフセットで制限する必要があります。
デフォルトでは、クエリを制限してもオフセットは考慮されません。したがって、デフォルトのオフセット値は0です。
たとえば、Dao
:
デフォルトのオフセット値は0であるため、以下の例1と2のクエリは同等です。
例
@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
で観察します リストまたはリスト内の任意の要素を取得するため)。
そのためには:
ダオで: :クエリを
に変更します@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.
そして、Log.dに最初の学生名を入力するために、mAllStudentsリストの最初の要素を返します
だから、あなたの活動で
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
の値は失われます;したがって、オブザーバーパターンを使用できなくなるため、リストを手動で更新して更新を確認する必要があります。
したがって、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);
そして、Daoのクエリ:
@Query("SELECT * FROM students LIMIT :limit OFFSET :offset")
List<Student> getAllStudents(int limit, int offset);