wie man das erste oder (beliebige) Element aus einer LiveData-Liste in der AndroidMVVM-Architektur erhält
Wenn Sie ein bestimmtes Element aus einer LiveData-Liste erhalten möchten, müssen Sie Ihre Abfrage mit einem Offset einschränken.
Standardmäßig wird beim Einschränken einer Abfrage kein Offset berücksichtigt; Der Standard-Offsetwert ist also 0.
Zum Beispiel in Ihrem Dao
:
Die folgenden Abfragen von Beispiel 1 und 2 sind äquivalent, da der Standard-Offset-Wert 0 ist.
Beispiel
@Query("SELECT * FROM students LIMIT :limit")
LiveData<List<Student>> getStudents(int limit);
// Query
getStudents(1); // returns the first row of the list
Beispiel 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
Hinweis: Hier gehe ich davon aus, dass Ihre Modellklasse Student
ist
Hier geht es um die erste Reihe; sondern um die Zeilennummer x
zurückzugeben dann müssen Sie den Versatz so manipulieren, dass er ist:x-1
, da der Offset ein 0-basierter Wert ist
Beispiel 3 (gleiche Dao-Abfrage wie Beispiel 2)
getStudents(1, 1); // returns the second row
getStudents(1, 4); // returns the fifth row
Wenn Sie mehr als eine Zeile zurückgeben möchten, müssen Sie das LIMIT
manipulieren Wert, um x
zurückzugeben Zeilen aus den Ergebnissen und schränken Sie dann die Abfrage mit x
ein .
getStudents(2, 1); // returns the second and third rows
getStudents(3, 4); // returns the fifth, sixth, and seventh rows
Ich hoffe, das beantwortet Ihre Frage
Bearbeiten gemäß den Kommentaren
Ich habe bereits eine Liste, die von einer anderen Abfrage zurückgegeben wird @Query("SELECT * FROM
students)
LiveData<List<Student>> getStudents();
Der zurückgegebene Wert ist also eine Liste. Ich möchte das erste Element aus der Liste erhalten. Diese Antwort gibt das erste Element wirklich zurück, aber ich muss alle Schritte durchlaufen (um diese Methode im ViewModel
zu definieren Klasse und beobachten Sie sie in der MainActivity
um die Liste oder irgendein Element in der Liste zu erhalten). Was ich brauche, ist, den ersten Wert in der Liste einzugeben, während ich die Funktion in der Repository-Klasse amüsiere. –
Jetzt verwenden Sie die folgende Abfrage
@Query("SELECT * FROM students")
LiveData<List<Student>> getStudents();
Und Sie möchten:
- Das erste oder ein beliebiges Element in der Liste abrufen. und dies gemäß dem oben Erwähnten zu tun
- Alle Schritte durchlaufen (um diese Methode im
ViewModel
zu definieren classund beobachten Sie es in derMainActivity
um die Liste oder irgendein Element in der Liste zu bekommen).
Um das zu tun:
In Dao: :Ändern Sie Ihre Abfrage in
@Query("SELECT * FROM students LIMIT :limit OFFSET :offset")
LiveData<List<Student>> getAllStudents(int limit, int offset);
Im Repository:
public class StudentRepository {
...
public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
return mDAO.getAllStudents(limit, offset);
}
}
In ViewModel:
public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
return mRepository.getAllStudents(limit, offset);
}
Aktiv:
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
}
}
});
}
Und um das zu testen:
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.
Und um das erste Element in der mAllStudents-Liste zurückzugeben, um den ersten Studentennamen in Log.d einzugeben
Also, in deiner Aktivität
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());
}
}
});
Bearbeiten ist es möglich, jedes Element der Liste zurückzugeben, ohne alle Schritte zu befolgen, z. B. das Schreiben einer Funktion in das ViewModeland, und beobachten Sie das in der MainActivity? Meine Frage ist, nicht alle Schritte zu befolgen.
Ja, das ist möglich, aber das obige Modell ist das von Google empfohlene Modell. Sie können eine List<Student>
zurückgeben von Dao
statt LiveData<List<Student>>
abfragen , aber die schlechten Nachrichten sind:
- Sie müssen das in einem separaten Hintergrundthread behandeln; weil die
LiveData
tun Sie das kostenlos. - Sie verlieren den Wert der
LiveData
; Sie müssen die Liste also manuell aktualisieren, um nach Aktualisierungen zu suchen, da Sie das Beobachtermuster nicht verwenden können.
Sie können also auf die Verwendung von ViewModel
verzichten und Repository
, und erledigen Sie alle Dinge aus der Aktivität wie folgt:
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);
Und die Abfrage für das Dao:
@Query("SELECT * FROM students LIMIT :limit OFFSET :offset")
List<Student> getAllStudents(int limit, int offset);