android - Android LiveData Observer 没有被第二次触发
问题描述
我正在开展一项允许用户过滤其搜索结果的活动。最初,我获取所有数据,但是当用户想要过滤它时,我需要调用另一个查询并更新视图。我为此使用 Android ROOM 和 ViewModel。
问题是每次我获取新数据时,我都需要创建一个新的观察者,因为旧的观察者“停止”启动。通常,这应该与一个观察者一起工作,每次更新数据时都会调用它。你能帮我理解为什么会这样吗?
活动:
package com.jds.fitnessjunkiess.getfitapp.Activities.ExercisesView;
import android.arch.lifecycle.ViewModelProviders;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import com.jds.fitnessjunkiess.getfitapp.Activities.ExercisesView.Adapters.ExercisesAdapter;
import com.jds.fitnessjunkiess.getfitapp.Data.ViewModels.ExerciseViewModel;
import com.jds.fitnessjunkiess.getfitapp.R;
public class ExercisesViewActivity extends AppCompatActivity implements View.OnClickListener {
private ExerciseViewModel exerciseViewModel;
private ExercisesAdapter recyclerViewerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exercises_view);
Toolbar toolbar = findViewById(R.id.toolbar_exercise_view_activity);
toolbar.setTitle("Exercises");
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
}
RecyclerView recyclerView = findViewById(R.id.exercise_view_recycle_viewer);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
this.recyclerViewerAdapter = new ExercisesAdapter();
recyclerView.setAdapter(recyclerViewerAdapter);
this.exerciseViewModel = ViewModelProviders.of(this).get(ExerciseViewModel.class);
this.exerciseViewModel.setFilters("", "");
// this.exerciseViewModel.selectAll();
this.exerciseViewModel.select().observe(this, exercises -> {
if (exercises != null) {
this.recyclerViewerAdapter.updateDataset(exercises);
}
});
Button button = findViewById(R.id.test_button);
button.setOnClickListener(this);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
break;
}
return true;
}
@Override
public void onClick(View v) {
this.exerciseViewModel.setFilters("", "");
// this.exerciseViewModel.select().observe(this, exercises -> {
// if (exercises != null) {
// this.recyclerViewerAdapter.updateDataset(exercises);
// }
// });
}
}
查看型号:
public class ExerciseViewModel extends AndroidViewModel {
ExercisesRepository repository;
LiveData<List<Exercise>> data;
public ExerciseViewModel(Application application) {
super(application);
this.repository = new ExercisesRepository(application);
}
public void setFilters(String muscleGroups, String type) {
this.data = this.repository.filterSelect(muscleGroups, type);
}
public LiveData<List<Exercise>> select() {
return data;
}
public void insert(Exercise exercise) {
this.repository.insert(exercise);
}
}
存储库
public class ExercisesRepository {
private ExerciseDao dao;
public ExercisesRepository(Application context) {
WorkoutRoomDatabase database = WorkoutRoomDatabase.getDb(context);
this.dao = database.exerciseDao();
}
public LiveData<List<Exercise>> filterSelect(String muscleGroups, String type) {
return this.dao.filterSelect("%" + muscleGroups + "%", "%" + type + "%");
}
public void insert(Exercise exercise) {
new insertAsyncTask(this.dao).execute(exercise);
}
private static class insertAsyncTask extends AsyncTask<Exercise, Void, Void> {
private ExerciseDao exerciseDao;
insertAsyncTask(ExerciseDao dao) {
exerciseDao = dao;
}
@Override
protected Void doInBackground(final Exercise... params) {
exerciseDao.insert(params[0]);
return null;
}
}
}
道:
@Dao
public interface ExerciseDao {
@Query("SELECT * FROM exercises WHERE muscleGroups LIKE :muscleGroup AND type LIKE :type")
LiveData<List<Exercise>> filterSelect(String muscleGroup, String type);
@Query("SELECT * FROM exercises")
LiveData<List<Exercise>> selectAll();
@Insert
void insert(Exercise exercise);
@Update
void update(Exercise exercise);
@Delete
void delete(Exercise exercise);
@Query("DELETE FROM exercises")
void deleteAll();
}
解决方案
您需要进行一些更改,因为您正在重新分配 LiveData 对象而不是添加过滤的项目。
您需要将LiveData> 数据称为MutableLiveData>并在setFilters方法中,您需要从存储库中获取 arraylist 并使用 setValue 方法将其添加到 MutableLiveData 中。
运动视图模型
MutableLiveData<List<Exercise>> data = new MutableLiveData<>();
public void setFilters(String muscleGroups, String type) {
List<Exercise> ex = this.repository.filterSelect(muscleGroups, type).getValue();
this.data.setValue(ex);
}
我希望它对你有帮助。
推荐阅读
- google-cloud-platform - 是否可以使用 Cloud Data Fusion FTP -> GCS -> BQ
- bash - 文件中的每一行列作为 awk 中的键
- firebase - FireStore 安全规则:如何限制更新/写入文档中的某个字段
- dataframe - CSV - 错误:BoundsError:和 Feather - 错误:InexactError: - Julia 编程
- reactjs - 在 React 中创建圆环图
- javascript - 如何在画布游戏中平滑移动玩家?
- javascript - Mongoose 返回错误代码 11000 重复索引
- android - 无法使其成为可启动的后台服务
- python - 使用简单数据时,metpy interpolate_to_grid 不适合我
- node.js - React-router-dom 重定向链接不起作用