Прежде всего, прочитав это Руководство по архитектуре приложения , вы получите общее представление о том, как эти архитектурные компоненты должны работать вместе.Основное правило:
каждый компонент зависит только от компонента на один уровень ниже его.
Это также означает, что каждый компонент не должен зависеть от компонентов над ним,Например, хранилище не должно зависеть ни от ViewModels, ни от Activity.Ваш код может быть реорганизован таким образом:
StudentRepository:
private StudentDao studentDao;
// public int stLevel;
// public void setStLvl() { // Do not read view components. Do not store their states.
// MainActivity mainActivity = new MainActivity();
// stLevel = mainActivity.getStLvl();
// }
public StudentRepository(Application application) {
AppDatabase database = AppDatabase.getInstance(application);
studentDao = database.studentDao();
// setStLvl();
}
.
.
.
public LiveData<List<Student>> getAllStudents() {
return studentDao.getAllStudents();
}
public LiveData<List<Student>> getStudentsByLevel(int stLevel) {
return studentDao.getStudentsByLevel(stLevel);
}
В приведенном выше примере хранилище выглядит так, как будто оно мало что делает, и это нормально, потому что есть толькоодин слой под ним, комната.На практике у вас могут быть другие источники данных, включая клиентов сети и кеш.Задача репозитория - абстрагировать всю логику источника данных.
ViewModel:
private MutableLiveData<Integer> studentLevel; // This will store the student level
private LiveData<List<Student>> studentsByLevel; // This will store the list of students
public StudentViewModel(@NonNull Application application) {
super(application);
repository = new StudentRepository(application);
studentLevel = new MutableLiveData<>();
// Place your logic inside the ViewModel
// Change in studentLevel will be reflected to studentsByLevel
studentsByLevel = Transformations.switchMap(studentLevel, lvl -> {
if (studentLevel == 0) {
return repository.getAllStudents();
} else {
repository.getStudentsByLevel(stLevel);
}
});
studentLevel.setValue(0) // Set initial student level.
}
.
.
.
public void setStudentLevel(int level) { // Change studentLevel anytime.
return studentLevel.setValue(level);
}
public LiveData<List<Student>> getStudentList() {
return studentsByLevel;
}
Я не фанат LiveData
, но вот что я хотел бы сделать.Сохраните всю свою логику во ViewModel и сделайте слой представления максимально простым.
И наконец, Activity:
private StudentViewModel studentViewModel
protected void onCreate(Bundle savedInstanceState) {
...
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
final StudentAdapter adapter = new StudentAdapter();
recyclerView.setAdapter(adapter);
studentViewModel = ViewModelProviders.of(this).get(StudentViewModel.class);
studentViewModel.observe(this, students -> {
adapter.submitList(students);
});
// studentViewModel.setValue(1) // call this function anywhere you like.
}
Над кодом будут показаны все учащиеся, потому что мы установили значение по умолчанию 0в модели представления.Позвоните studentViewModel.setValue(/*any integer*/)
, чтобы переключить список на любой уровень.