Syed Umair
Syed Umair

Reputation: 1602

ViewModel onChanged() called infinitely

I calculate percent when checkbox on recyclerView item is checked or unchecked. It works fine but when I add a new item to recyclerView sometimes onChanged() is called infinitely and UI freezes.

In 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;
}

When new Item (task) is added using another activity, onSaveButtonclicked method is used

 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
        }
    });
}

Upvotes: 0

Views: 192

Answers (1)

Syed Umair
Syed Umair

Reputation: 1602

I solved this issue. I just used onClickListener on Checkbox instead of OnCheckedChangeListener. OnCheckedChanged() was getting called again and again in a loop. But now it works fine with onClickListener.

Upvotes: 1

Related Questions