1

In my application i have horizontal list view. On Item select I want to change that selected Item background color and it's text view color. i have figured out that part. But how to reset background color and text view color of previously selected item. here's my adapter class.

public class DateRangeListViewAdapter extends RecyclerView.Adapter<DateRangeListViewAdapter.ContentViewHolder>  {

private ItemClickListener itemClickListener;
private LayoutInflater inflater;
private ArrayList<String> data;
private Context context;
private int dataType;
private int previousSelectedPosition;
private static final int DATE_TYPE = 1;
private static final int STATUS_TYPE = 2;

public DateRangeListViewAdapter(ArrayList<String> data, Context context,int dataType) {
    this.data = data;
    this.context = context;
    this.dataType = dataType;
    inflater  = LayoutInflater.from(context);
    previousSelectedPosition = -1;
}

public void setItemClickListener(ItemClickListener itemClickListener) {
    this.itemClickListener = itemClickListener;
}

@Override
public ContentViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.custom_date_range_list_item,parent,false);
    return new ContentViewHolder(view);
}

@Override
public void onBindViewHolder(ContentViewHolder holder, int position) {
    String name = data.get(position);
    holder.dateText.setText(name);
}

@Override
public int getItemCount() {
    return data.size();
}


public class ContentViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    private FrameLayout main;
    private TextView dateText;

    public ContentViewHolder(View itemView) {
        super(itemView);
        itemView.setOnClickListener(this);
        main = (FrameLayout) itemView.findViewById(R.id.main_layout);
        dateText = (TextView) itemView.findViewById(R.id.date_name);
    }

    @Override
    public void onClick(View v) {

        //Selected item color change
        main.setBackground(ContextCompat.getDrawable(context,R.drawable.date_range_selected_item_background));
        dateText.setTextColor(ContextCompat.getColor(context,R.color.colorPrimary));

        if(itemClickListener!=null){
            itemClickListener.onItemClick(v,this.getLayoutPosition(),dataType,getOldPosition());
        }
    }
}

public interface ItemClickListener{
    public void onItemClick(View v, int position,int dataType,int oldPosition);
    }
}

2 Answers2

0

You basically want to make good use of your int flag, previousSelectedPosition, to keep track of the list item's position that was clicked, invoke notifyDataSetChanged(), and then set the flag as part of a conditional statement within onBindViewHolder() to update ViewHolder's views accordingly as they continuously get binded. Try the following changes:

ViewHolder's onClick():

@Override
public void onClick(View v) {
    if (itemClickListener!=null) {
        previousSelectedPosition = getAdapterPosition();

        notifyDataSetChanged();

        itemClickListener.onItemClick(v,this.getLayoutPosition(),dataType,getOldPosition());
    }
}

RecyclerView.Adapter's onBindViewHolder():

@Override
public void onBindViewHolder(ContentViewHolder holder, int position) {
    String name = data.get(position);
    holder.dateText.setText(name);

    if (previousSelectedPosition == position) {
        main.setBackground(ContextCompat.getDrawable(context,R.drawable.date_range_selected_item_background));
        dateText.setTextColor(ContextCompat.getColor(context,R.color.colorPrimary));
    } else {
        // TODO: Configure the FrameLayout and TextView here for initial runtime as well as back to default
    }
}

... and yes, make sure to keep previousSelectedPosition initialized as -1 for the initial runtime just so the condition in onBindViewHolder() wouldn't matter until the flag updates (after a list item is clicked, that is).

DaveNOTDavid
  • 1,753
  • 5
  • 19
  • 37
  • Thanks for the answer. It's working A little doubt, when calling `notifyDataSetChanged()` doesn't it going to re draw entire list view ? If yes isn't this bad for performance.I thought there might be a way to find list view item by position and change that only to default design when clicking second item. – Chathuranga Shan Jayarathna Jul 02 '17 at 04:42
  • @ChathurangaShanJayarathna notifyDataSetChanged() only updates the list items that are currently on-screen as opposed to rebuilding the whole list, so no, it's not expensive in memory. As for your issue, I'm sure there's a way, but it's good practice to use my approach since updating the UI of an individual row of a list consisting of many list items (especially when new rows are inserted) of say, 100 rows off-screen, leads to a bug where "every other" list item is updated as well. This tutorial video may help: https://www.youtube.com/watch?v=Ntrf-sWSrNs – DaveNOTDavid Jul 02 '17 at 05:34
0

Your OnClickListener does not work perfectly. You just need to implements your ViewHolder from you "ItemClickListener" interface. And add this line in onCreateViewHolder :

View view = inflater.inflate(R.layout.custom_date_range_list_item,parent,false);
ContentViewHolder cVh =  ContentViewHolder(view);view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            cVh.onItemClick(v,this.getLayoutPosition(),cVh .dataType,cVh .getOldPosition());

        }
    });return cVh
Ajeet Choudhary
  • 1,969
  • 1
  • 17
  • 41
VahabGh
  • 11
  • 4