无限调用的ViewModel onChanged()

时间:2020-05-23 01:22:11

标签: android viewmodel android-livedata observer-pattern android-mvvm

当recyclerView项目上的复选框处于选中状态或未选中状态时,我会计算百分比。效果很好,但是当我向recyclerView添加新项目时,有时会无限调用onChanged()且UI冻结。

在MainActivity中

    @Override
public void onCheckBoxCheckListener(final TaskEntry taskEntry, final boolean isChecked) {

    AppExecutors.getInstance().diskIO().execute(new Runnable() {
        @Override
        public void run() {
            taskEntry.setChecked(isChecked);
            mDb.taskDao().updateTask(taskEntry);

        }
    });

}

private void setupViewModel() {
    MainViewModel viewModel = new ViewModelProvider(this).get(MainViewModel.class);
    viewModel.getTasks().observe(this, new Observer<List<TaskEntry>>() {
        @Override
        public void onChanged(List<TaskEntry> taskEntries) { 

            calculatePercent(taskEntries);
            mprogressBar.setProgress((int)mTotalProgressPercent);
            mProgressValue.setText((int)mTotalProgressPercent + " %");

            //this gets logged infinity when a new item is added
            Log.d("setupVM", " called TotalPercent = " + (int)mTotalProgressPercent );

            mAdapter.setTasks(taskEntries);
        }
    });
}

private void calculatePercent(List<TaskEntry> taskEntries) {
    int countChecked = 0;
    for(TaskEntry i: taskEntries){
        if(i.isChecked()) countChecked++;
    }
    mTotalProgressPercent = (double)countChecked/taskEntries.size() *100;
}

MainViewModel

public class MainViewModel extends AndroidViewModel {

private LiveData<List<TaskEntry>> tasks;

public MainViewModel(@NonNull Application application){
    super(application);
    AppDatabase database = AppDatabase.getInstance(this.getApplication());
    tasks = database.taskDao().loadAllTasks();
}

public LiveData<List<TaskEntry>> getTasks() {
    return tasks;
}

使用其他活动添加新项目(任务)时,将使用onSaveButtonclicked方法

 public void onSaveButtonClicked() {
    String description = mEditText.getText().toString();
    int priority = getPriorityFromViews();
    Date date = new Date();

    final TaskEntry taskEntry = new TaskEntry(description, priority, date, false );

    AppExecutors.getInstance().diskIO().execute(new Runnable() {
        @Override
        public void run() {
            if(mTaskId == DEFAULT_TASK_ID){
                mDb.taskDao().insertTask(taskEntry);
            }else {
                taskEntry.setId(mTaskId);  //for updating any task, works fine
                mDb.taskDao().updateTask(taskEntry);
            }
            finish(); // return to main activity
        }
    });
}

1 个答案:

答案 0 :(得分:0)

我解决了这个问题。我只是在Checkbox上使用了onClickListener而不是OnCheckedChangeListener。 OnCheckedChanged()在循环中一次又一次被调用。 但是现在它可以与onClickListener一起正常工作。