hvordan man får det første eller (et hvilket som helst) element fra en LiveData List i AndroidMVVM arkitektur
Hvis du ønsker at få et bestemt element fra en LiveData-liste, skal du begrænse din forespørgsel med en offset.
Som standard betragter begrænsning af en forespørgsel ikke en forskydning af den; så standard offset-værdien er 0.
For eksempel i din Dao
:
Nedenstående forespørgsler i eksempel 1 og 2 er ækvivalente, fordi standard offsetværdien er 0.
Eksempel
@Query("SELECT * FROM students LIMIT :limit")
LiveData<List<Student>> getStudents(int limit);
// Query
getStudents(1); // returns the first row of the list
Eksempel 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
Bemærk: Her går jeg ud fra, at din modelklasse er Student
Det drejer sig om den første række; men for at returnere rækkenummer x
så skal du manipulere forskydningen til at være:x-1
, da forskydningen er 0-baseret værdi
Eksempel 3 (samme Dao-forespørgsel som eksempel 2)
getStudents(1, 1); // returns the second row
getStudents(1, 4); // returns the fifth row
Hvis du vil returnere mere end én række, skal du manipulere LIMIT
værdi, så for at returnere x
rækker fra resultaterne, og begræns derefter forespørgslen med x
.
getStudents(2, 1); // returns the second and third rows
getStudents(3, 4); // returns the fifth, sixth, and seventh rows
Håber dette løser dit spørgsmål
Rediger i henhold til kommentarer
Jeg har allerede en liste returneret af en anden forespørgsel @Query("SELECT * FROM
students)
LiveData<List<Student>> getStudents();
Så den returnerede værdi er en liste. Jeg vil gerne hente det første element fra listen. Dette svar returnerer virkelig det første element, men jeg skal bestå alle trinene (for at definere denne metode i ViewModel
klasse og observer den i MainActivity
for at få listen eller ethvert element på listen). Det, jeg skal bruge, er at skrive den første værdi på listen, mens jeg underholder funktionen i repository-klassen. –
Nu bruger du nedenstående forespørgsel
@Query("SELECT * FROM students")
LiveData<List<Student>> getStudents();
Og du vil:
- Hent det første eller et hvilket som helst element på listen. og at gøre det i henhold til det, der er nævnt ovenfor
- Bestå alle trinene (for at definere denne metode i
ViewModel
). klasse og observer det iMainActivity
for at få listen eller ethvert element på listen).
Så for at gøre det:
I Dao: :Skift din forespørgsel til
@Query("SELECT * FROM students LIMIT :limit OFFSET :offset")
LiveData<List<Student>> getAllStudents(int limit, int offset);
I lager:
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
}
}
});
}
Og for at teste 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.
Og for at returnere det første element i mAllStudents-listen for at indtaste det første elevnavn 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());
}
}
});
Rediger er det muligt at returnere et hvilket som helst element på listen uden at følge alle trin, såsom at skrive en funktion i ViewModeland observere det i MainActivity? Mit spørgsmål er ikke at følge alle trinene.
Ja, det er muligt, men ovenstående model er den anbefalede model af Google. Du kan returnere en List<Student>
fra Dao
forespørgsel i stedet for LiveData<List<Student>>
, men de dårlige nyheder er:
- Du skal håndtere det i en separat baggrundstråd; fordi
LiveData
gør det gratis. - Du mister værdien af
LiveData
; så du skal manuelt opdatere listen for at kontrollere enhver opdatering, da du ikke vil være i stand til at bruge observatørmønsteret.
Så du kan undlade at bruge ViewModel
og Repository
, og gør alle tingene fra aktiviteten som følger:
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);
Og forespørgslen til Dao:
@Query("SELECT * FROM students LIMIT :limit OFFSET :offset")
List<Student> getAllStudents(int limit, int offset);