SQLite
 sql >> Datenbank >  >> RDS >> SQLite

Wie bekomme ich das erste oder (beliebige) Element aus einer LiveData-Liste in der Android-MVVM-Architektur?

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:

  1. Das erste oder ein beliebiges Element in der Liste abrufen. und dies gemäß dem oben Erwähnten zu tun
  2. Alle Schritte durchlaufen (um diese Methode im ViewModel zu definieren classund beobachten Sie es in der MainActivity 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:

  1. Sie müssen das in einem separaten Hintergrundthread behandeln; weil dieLiveData tun Sie das kostenlos.
  2. 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);