change RecyclerView's color dynamically

61 Views Asked by At

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

}
2

There are 2 best solutions below

2
Santanu Sur On BEST ANSWER

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

1
2MuchSmoke On

Here is the sample code, after reviewing your code you have to define the card inside the ViewHolder

isImp = Boolean.parseBoolean(cursor.getString(cursor.getColumnIndex(DBContracts.Tasks.T_IS_IMP)));
if (isImp){
    holder.card.setBackgroundColor(context.getResources().getColor(R.color.isImpColor));
} else {
   //set the card normal color here
     holder.card.setBackGroundColor(*insert your normal color here*);
}