SQLite
 sql >> Base de données >  >> RDS >> SQLite

comment obtenir le premier ou (n'importe quel) élément d'une liste LiveData dans l'architecture Android MVVM ?

comment obtenir le premier ou (n'importe quel) élément d'une liste LiveData dans l'architecture AndroidMVVM

Si vous souhaitez obtenir un élément particulier d'une liste LiveData, vous devez limiter votre requête avec un décalage.

Par défaut, la limitation d'une requête ne prend pas en compte son décalage ; donc la valeur de décalage par défaut est 0.

Par exemple, dans votre Dao :

Les requêtes ci-dessous des exemples 1 et 2 sont équivalentes, car la valeur de décalage par défaut est 0.

Exemple

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

// Query
getStudents(1); // returns the first row of the list

Exemple 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

Remarque : Ici, je suppose que votre classe de modèle est Student

Il s'agit de la première rangée ; mais pour renvoyer le numéro de ligne x alors vous devez manipuler le décalage pour qu'il soit :x-1 , car le décalage est une valeur de base 0

Exemple 3 (même requête Dao que l'exemple 2)

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

Si vous souhaitez renvoyer plusieurs lignes, vous devez manipuler le LIMIT valeur, donc pour retourner x lignes des résultats, puis limitez la requête avec x .

getStudents(2, 1); // returns the second and third rows
getStudents(3, 4); // returns the fifth, sixth, and seventh rows

J'espère que cela répond à votre question

Modifier selon les commentaires

J'ai déjà une liste retournée par une autre requête @Query("SELECT * FROM students) LiveData<List<Student>> getStudents(); La valeur renvoyée est donc une liste. Je veux obtenir le premier élément de la liste. Cette réponse renvoie vraiment le premier élément, mais je dois passer toutes les étapes (pour définir cette méthode dans le ViewModel classe et observez-la dans MainActivity afin d'obtenir la liste ou tout élément de la liste). Ce dont j'ai besoin, c'est de taper la première valeur de la liste pendant que j'amuse la fonction dans la classe de référentiel. –

Vous utilisez maintenant la requête ci-dessous

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

Et vous voulez :

  1. Obtenir le premier ou n'importe quel élément de la liste. et de le faire selon ce qui est mentionné ci-dessus
  2. Passez toutes les étapes (pour définir cette méthode dans le ViewModel classer et l'observer dans le MainActivity afin d'obtenir la liste ou tout élément de la liste).

Alors pour faire ça :

En Dao :  :Modifiez votre requête en

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

Dans le référentiel :

public class StudentRepository {

    ...

    public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
        return mDAO.getAllStudents(limit, offset);
    }
}

Dans ViewModel :

public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
    return mRepository.getAllStudents(limit, offset);
}

En activité :

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

            }
        }
    });
}

Et pour tester ça :

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.

Et pour renvoyer le premier élément de la liste mAllStudents afin de saisir le premier nom d'élève dans le Log.d

Alors, dans votre activité

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 est-il possible de retourner n'importe quel élément de la liste sans suivre toutes les étapes comme écrire une fonction dans le ViewMode et observer cela dans la MainActivity ? Ma question n'est pas de suivre toutes les étapes.

Oui, c'est possible, mais le modèle ci-dessus est le modèle recommandé par Google, vous pouvez renvoyer une List<Student> de Dao requête au lieu de LiveData<List<Student>> , mais la mauvaise nouvelle est :

  1. Vous devez gérer cela dans un thread d'arrière-plan séparé ; car les LiveData faites-le gratuitement.
  2. Vous perdrez la valeur du LiveData; vous devez donc actualiser manuellement la liste pour vérifier toute mise à jour car vous ne pourrez pas utiliser le modèle d'observateur.

Ainsi, vous pouvez omettre d'utiliser ViewModel et Repository , et faites toutes les choses de l'activité comme suit :

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

Et la requête pour le Dao :

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