javaandroidandroid-recyclerviewadaptor

change RecyclerView's color dynamically


In my app, I have a todo list. when the user checks the task as important, it's background gets red; It works somehow but after returning to mainActivity, it changes random list item's color!

here everything is Ok.

But here task 4 is not checked as important and task 5 is checked as important!

Here is my code for recyclerViewAdaptor:

@Override
public void onBindViewHolder(final MyHolder holder, int position) {
    if (!cursor.moveToPosition(position))
        return;

    final long id = cursor.getLong(cursor.getColumnIndex(DBContracts.Tasks._ID));
    time = cursor.getInt(cursor.getColumnIndex(DBContracts.Tasks.T_TIME));
    hour = String.valueOf(time / 60);
    min = String.valueOf(time % 60);
    if (Integer.parseInt(hour) < 10){
        hour = "0" + hour;
    }
    if (Integer.parseInt(min) < 10){
        min = "0" + min;
    }
    //!!!!!!!!!!!!here!!!!!!!!!!!!!
    //change color if isImp is true
    isImp = Boolean.parseBoolean(cursor.getString(cursor.getColumnIndex(DBContracts.Tasks.T_IS_IMP)));
    if (isImp){
        card.setBackgroundColor(context.getResources().getColor(R.color.isImpColor));
    }else {
        card.setBackgroundColor(context.getResources().getColor(R.color.isNotImpColor));
    }
    holder.name.setText(cursor.getString(cursor.getColumnIndex(DBContracts.Tasks.T_NAME)));
    holder.time.setText(hour + ":" + min);
    holder.itemView.setTag(id);
    holder.isDone.setOnClickListener(new View.OnClickListener() {
        @Override
            public void onClick(View v) {
                vb.vibrate(100);
                DBOps.Ops.done(id,"true");
                swap(DBOps.Ops.getEmAll(false));
            }});
}

And here is the code for adding a new task:

public class AddNewTaskActivity extends AppCompatActivity {

EditText taskName;
TimePicker taskTime;
Switch aSwitch;
boolean isImp = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_new_task);
    if (getSupportActionBar() != null) {
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }
    setTitle("New task");

    taskName = (EditText) findViewById(R.id.taskName);
    taskTime = (TimePicker) findViewById(R.id.timePicker);
    aSwitch = (Switch) findViewById(R.id.isImp);
    aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (aSwitch.isChecked()) {
                isImp = true;
            } else {
                isImp = false;
            }
        }
    });

    taskTime.setIs24HourView(true);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.add_new_task_menu,menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    switch (id){
        case R.id.addNew :
            addNewTaskToDB();
            break;
        case android.R.id.home :
            onBackPressed();
    }
    return super.onOptionsItemSelected(item);
}

private void addNewTaskToDB() {
    if (taskName.length() == 0){
        Toast.makeText(this,"Type something as title.",Toast.LENGTH_SHORT).show();
    }else {
        int time = taskTime.getHour() * 60 + taskTime.getMinute();
        DBOps.Ops.addNewTaskOp(
                taskName.getText().toString().trim(),
                time,
                String.valueOf(isImp));
        setAlarm();
        finish();
    }
}

public void setAlarm(){

    Calendar calendar = Calendar.getInstance();

    calendar.set(Calendar.HOUR_OF_DAY,taskTime.getHour());
    calendar.set(Calendar.MINUTE,taskTime.getMinute());
    calendar.set(Calendar.SECOND,0);

    Intent intent = new Intent(this,NotificationReciever.class);
    intent.putExtra("name",taskName.getText());

    PendingIntent pendingIntent = PendingIntent.getBroadcast(this,1,intent,PendingIntent.FLAG_UPDATE_CURRENT);

    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY,pendingIntent);

}

Solution

  • RecyclerView recycles its items ...so directly changing an item color may change the color of other items while scrolling ..to achieve this you need to apply a small trick (by taking a boolean isChecked variable in the model class.

    For reference check this out.

    How to implement multi-select in RecyclerView?

    Edit

    change your card to holder.card