sganu
sganu

Reputation: 60

RecyclerView onClick problems

I have been working on RecyclerView and when a user clicks on an item I want the recyclerview panel to be changed. For simple testing purposes I am making the text of the recyclerview item red when clicked upon. The clicking properly but when I scroll the RecyclerView, other items randomly turn red. These random items are not clicked upon and are becoming red by themselves when I scroll. I think my problem should be in the onClick method.

public class interestAdapter extends RecyclerView.Adapter<interestAdapter.MyViewHolder> {
private LayoutInflater inflater;
private Context context;
public ArrayList<String> data = new ArrayList();
public static MyViewHolder.ViewHolderClick click;
//public static MyViewHolder.ViewHolderClick click;



public interestAdapter(Context context, ArrayList<String> objects) {
    this.context = context;
    inflater = LayoutInflater.from(context);
    for(int i = 0; i < objects.size(); i++) {
        data.add(objects.get(i));
    }
}

public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.interestpanel, parent, false);
    MyViewHolder holder = new MyViewHolder(view);
    return holder;

}

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

public void setClickListener(MyViewHolder.ViewHolderClick clicker) {
    this.click = clicker;
}

public void onBindViewHolder(MyViewHolder holder, int position) {
    String current = data.get(position);
    holder.category.setText(current);


}

static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { //implements View.onClickListener {
    TextView category;
    public MyViewHolder(View itemView) {
        super(itemView);
        //itemView.setOnClickListener(this);

        category = (TextView) itemView.findViewById(R.id.category);
        category.setOnClickListener(this);


    }

    @Override
    public void onClick(View v) {

            MyViewHolder holder = new MyViewHolder(v);
            holder.category.setTextColor(Color.RED);

    }
    public TextView getCate() {
        return category;
    }

    public static interface ViewHolderClick {
        public void clicked(View view, int position);
    }


}

} `

Upvotes: 3

Views: 1400

Answers (3)

LEGEND MORTAL
LEGEND MORTAL

Reputation: 336

I have done this in onBindViewHolder() method of RecyclerView.Adapter class

@Override
public void onBindViewHolder(final MyRecyclerViewAdapter.MyViewHolder viewHolder, final int position) {

    final MyModel myModel = mMyModelArrayList.get(position);
    viewHolder.aTextView.setText(myModel.getA());


    View view = viewHolder.itemView;

    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Toast.makeText(mContext, "View where A: " + myModel.getA() + " is Clicked", Toast.LENGTH_SHORT).show();
        }
    });

}

Imp Part

Dont forget to add android:clickable="true" and android:focusable="true" in your RecyclerViews Layout i.e. Parent Layout

Eg:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:focusable="true">

By this you can enable clicking on your RecyclerViews particular View

Explanation

In onBindViewHolder() method of your RecyclerView.Adapter class you can get ViewHolders Class view by View view = viewHolder.itemView;

So by using that view you can set onClick event for that particular Item Click of RecyclerView

Upvotes: 0

Karan
Karan

Reputation: 2130

RecyclerView uses same row reference multiple times via myHolder object. Problem is at :

MyViewHolder holder = new MyViewHolder(v);  //this holder has multiple reference in recyclerView
holder.category.setTextColor(Color.RED);

As Piyush suggests correctly, maintain a field in your model for click (boolean). And render clicks with check on this boolean. update the boolean at your onclick

What I normally do is:

public void onBindViewHolder(final ContactViewHolder convosViewHolder, final int i) {

        convosViewHolder.name.setText(contacts.get(i).getName());
        convosViewHolder.phone.setText(contacts.get(i).getNumber());

        convosViewHolder.cv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               //turn red here
        });
    }

You can try either. hope it helps.

Upvotes: 1

Piyush
Piyush

Reputation: 1973

The problem is quite straight forward as we know recycler view recycle the view one you have changed the color of one view in the list view the color of that view remain of that color in your case red.So at the time of bind view holder you need to change the color back to normal ifs not clicked in other way you have to maintain the position of the clicked view and change the color accordingly.

Upvotes: 1

Related Questions