sql >> Databasteknik >  >> RDS >> SQLite

hur får man det första eller (vilket som helst) element från en LiveData List i Android MVVM-arkitektur?

hur man får det första eller (vilket som helst) element från en LiveData List i AndroidMVVM-arkitektur

Om du vill hämta ett visst element från en LiveData-lista måste du begränsa din fråga med en offset.

Som standard betraktar begränsningen av en fråga inte som en förskjutning till den; så standardvärdet för offset är 0.

Till exempel i din Dao :

Frågorna nedan i exempel 1 och 2 är likvärdiga, eftersom standardvärdet för offset är 0.

Exempel

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

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

Exempel 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

Obs! Här antar jag att din modellklass är Student

Det här handlar om den första raden; men för att returnera radnummer x då måste du manipulera offseten så att den blir:x-1 , eftersom offset är 0-baserat värde

Exempel 3 (Samma Dao-fråga som exempel 2)

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

Om du vill returnera mer än en rad, måste du manipulera LIMIT värde, så att returnera x rader från resultaten och begränsa sedan frågan med x .

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

Hoppas detta löser din fråga

Redigera enligt kommentarer

Jag har redan en lista som returneras av en annan fråga @Query("SELECT * FROM students) LiveData<List<Student>> getStudents(); Så det returnerade värdet är en lista. Jag vill hämta det första elementet från listan. Det här svaret returnerar det första elementet, men jag måste klara alla stegen (för att definiera denna metod i ViewModel klass och observera den i MainActivity för att få listan eller något element i listan). Vad jag behöver är att skriva det första värdet i listan medan jag roar funktionen i förvarsklassen. –

Nu använder du nedanstående fråga

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

Och du vill:

  1. Hämta det första eller något annat element i listan. och att göra det enligt vad som nämns ovan
  2. Godkänn alla steg (för att definiera denna metod i ViewModel). klass och observera det i MainActivity för att få listan eller något element i listan).

Så för att göra det:

I Dao: :Ändra din fråga till

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

I arkivet:

public class StudentRepository {

    ...

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

I ViewModel:

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

I aktivitet:

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

            }
        }
    });
}

Och för att testa det:

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.

Och för att returnera det första elementet i mAllStudents-listan för att skriva in det första elevnamnet i Log.d

Så, i din aktivitet

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

Redigera är det möjligt att returnera valfritt element i listan utan att följa alla steg som att skriva en funktion i ViewModeland observera det i MainActivity? Min fråga är att inte följa alla stegen.

Ja det är möjligt, men ovanstående modell är den rekommenderade modellen av Google. Du kan returnera en List<Student> från Dao fråga istället för LiveData<List<Student>> , men de dåliga nyheterna är:

  1. Du måste hantera det i en separat bakgrundstråd; eftersom LiveData gör det gratis.
  2. Du kommer att förlora värdet på LiveData; så du måste uppdatera listan manuellt för att kontrollera eventuella uppdateringar eftersom du inte kommer att kunna använda observatörsmönstret.

Så du kan utelämna ViewModel och Repository , och gör alla saker från aktiviteten enligt följande:

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

Och frågan om Dao:

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



  1. Hur man ställer in MySQL-replikering i RHEL, Rocky och AlmaLinux

  2. Hitta skillnaden mellan tidsstämplar i sekunder i PostgreSQL

  3. Se om en tabell har en DEFAULT-begränsning i SQL Server med OBJECTPROPERTY()

  4. Liknande UTF-8-strängar för autokompletteringsfält