jak získat první nebo (jakýkoli) prvek ze seznamu LiveData v architektuře AndroidMVVM
Pokud chcete získat konkrétní prvek ze seznamu LiveData, musíte svůj dotaz omezit pomocí posunu.
Ve výchozím nastavení omezení dotazu nezvažuje jeho posun; takže výchozí hodnota offsetu je 0.
Například ve vašem Dao
:
Níže uvedené dotazy z příkladu 1 a 2 jsou ekvivalentní, protože výchozí hodnota offsetu je 0.
Příklad
@Query("SELECT * FROM students LIMIT :limit")
LiveData<List<Student>> getStudents(int limit);
// Query
getStudents(1); // returns the first row of the list
Příklad 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
Poznámka: Zde předpokládám, že vaše modelová třída je Student
Toto je o první řadě; ale vrátit číslo řádku x
pak musíte upravit posun tak, aby byl:x-1
, protože offset je hodnota založená na 0
Příklad 3 (Stejný dotaz Dao jako příklad 2)
getStudents(1, 1); // returns the second row
getStudents(1, 4); // returns the fifth row
Pokud chcete vrátit více než jeden řádek, musíte manipulovat s LIMIT
hodnotu, takže vrátíte x
řádků z výsledků a poté omezte dotaz pomocí x
.
getStudents(2, 1); // returns the second and third rows
getStudents(3, 4); // returns the fifth, sixth, and seventh rows
Doufám, že to vyřeší vaši otázku
Upravte podle komentářů
Již mám seznam vrácený jiným dotazem
@Query("SELECT * FROM
students)
LiveData<List<Student>> getStudents();
Takže vrácená hodnota je seznam. Chci získat první prvek ze seznamu. Tato odpověď skutečně vrací první prvek, ale musím projít všemi kroky (k definování této metody vViewModel
třídu a sledujte ji vMainActivity
za účelem získání seznamu nebo jakéhokoli prvku v seznamu). Co potřebuji, je napsat první hodnotu v seznamu, zatímco mě baví funkce ve třídě úložiště. –
Nyní používáte níže uvedený dotaz
@Query("SELECT * FROM students")
LiveData<List<Student>> getStudents();
A vy chcete:
- Získejte první nebo jakýkoli prvek v seznamu. a učinit tak podle toho, co je uvedeno výše
- Proveďte všechny kroky (chcete-li tuto metodu definovat v
ViewModel
class a sledujte to vMainActivity
za účelem získání seznamu nebo jakéhokoli prvku v seznamu).
Chcete-li to udělat:
V Dao: :Změňte svůj dotaz na
@Query("SELECT * FROM students LIMIT :limit OFFSET :offset")
LiveData<List<Student>> getAllStudents(int limit, int offset);
V úložišti:
public class StudentRepository {
...
public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
return mDAO.getAllStudents(limit, offset);
}
}
V ViewModel:
public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
return mRepository.getAllStudents(limit, offset);
}
V aktivitě:
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
}
}
});
}
A otestovat to:
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.
A vrátit první prvek v seznamu mAllStudents, aby bylo možné zadat jméno prvního studenta do Log.d
Takže ve vaší aktivitě
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());
}
}
});
Upravit je možné vrátit jakýkoli prvek seznamu bez provedení všech kroků, jako je psaní funkce v ViewModeland, pozorujte to v MainActivity? Moje otázka zní, abyste neprováděli všechny kroky.
Ano, je to možné, ale výše uvedený model je model doporučený společností Google. Můžete vrátit List<Student>
od Dao
dotaz místo LiveData<List<Student>>
, ale špatná zpráva je:
- To musíte zvládnout v samostatném vláknu na pozadí; protože
LiveData
udělejte to zdarma. - Ztratíte hodnotu
LiveData
; takže musíte ručně aktualizovat seznam, abyste zkontrolovali jakoukoli aktualizaci, protože nebudete moci použít vzor pozorovatele.
Takže můžete vynechat pomocí ViewModel
a Repository
a všechny věci z aktivity proveďte následovně:
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);
A dotaz na Dao:
@Query("SELECT * FROM students LIMIT :limit OFFSET :offset")
List<Student> getAllStudents(int limit, int offset);