我有一个students_table,并且存储了不同级别的学生。我想按一个级别显示学生,而隐藏其他级别。 我选择学生显示如下:
if (id == R.id.beginners) {
stLvl = 0;
}else if (id == R.id.intermediate) {
stLvl = 1;
}else if (id == R.id.advanced) {
stLvl = 2;
}else if (id == R.id.high_level) {
stLvl = 3;
}
showStud();
这里是showStud();
public void showStud() {
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
final StudentAdapter adapter = new StudentAdapter();
recyclerView.setAdapter(adapter);
setStLvl(stLvl);
if (stLvl == 0) {
studentViewModel = ViewModelProviders.of(this).get(StudentViewModel.class);
studentViewModel.getAllStudents().observe(this, new Observer<List<Student>>() {
@Override
public void onChanged(@Nullable List<Student> students) {
// update RecyclerView
adapter.submitList(students);
}
});
}else {
studentViewModel = ViewModelProviders.of(this).get(StudentViewModel.class);
studentViewModel.getStudentsByLevel().observe(this, new Observer<List<Student>>() {
@Override
public void onChanged(@Nullable List<Student> students) {
// update RecyclerView
adapter.submitList(students);
}
});
}
}
第一次运行代码时,无论stLvl的值如何,它都可以完美运行,但是当我更改代码时,它的值没有显示我想要的东西,或者根本没有显示。 我认为问题出在这一行:
studentViewModel = ViewModelProviders.of(this).get(StudentViewModel.class);
第一次运行,它工作正常,转到StudentViewModel.class来执行应做的工作,但是第二次只是跳转到下一行代码,而无需转到StudentViewModel.class。 我究竟做错了什么?预先谢谢你!
答案 0 :(得分:0)
是的,您是对的,实际上我是android编程的初学者。这是StudentViewModel:
private StudentDao studentDao;
private LiveData<List<Student>> allStudents;
private LiveData<List<Student>> studentsByLevel;
public int stLevel;
public void setStLvl() {
MainActivity mainActivity = new MainActivity();
stLevel = mainActivity.getStLvl();
}
public StudentRepository(Application application) {
AppDatabase database = AppDatabase.getInstance(application);
studentDao = database.studentDao();
setStLvl();
studentsByLevel = studentDao.getStudentsByLevel(stLevel);
allStudents = studentDao.getAllStudents();
}
.
.
.
public LiveData<List<Student>> getAllStudents() {
return allStudents;
}
public LiveData<List<Student>> getStudentsByLevel(int stLevel) {
return studentsByLevel;
}
StudentRepository:
@Query("SELECT * FROM student_table WHERE level = :level")
LiveData<List<Student>> getStudentsByLevel(int level);
在StudentDao中,我有:
io.emit('match-found', {
lobbyID: lobby._id,
enemyID: enemyLobby._id,
matchID: newMatch._id
});
我希望我提供了足够的数据。
答案 1 :(得分:0)
首先,阅读本Guide to app architecture将有助于您大致了解这些体系结构组件应如何协同工作。经验法则是
每个组件仅取决于其下一级的组件。
这也意味着每个组件都不应依赖于其上方的组件。例如,存储库不应既不依赖于ViewModel,也不依赖于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);
}
在上面的示例中,存储库看起来并没有做很多事情,这是正常的,因为它下面只有一层,即Room。实际上,您可以拥有其他数据源,包括网络客户端和缓存。存储库的工作是抽象所有数据源逻辑。
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中,并使视图层尽可能简单。
最后,活动:
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.
}
上面的代码将显示所有学生,因为我们在viewmodel中将默认值设置为0。致电studentViewModel.setValue(/*any integer*/)
,将列表切换到任意级别。