AhChing11
AhChing11

Reputation: 155

How do I change the background of a specific item onClick in a RecyclerView?

Im trying to make a selected item in the RecyclerView to change it's background when it is clicked, but once the other item in the RecyclerView is clicked, that item's background will be changed and the previously clicked item will change back to original.

I only manage to make the item change back to orignal(white background) when it is clicked the second time.

Any help please?

This is my RecyclerView Adapter

public class CharityListAdapter extends RecyclerView.Adapter<CharityListAdapter.CharityListViewHolder> {
    String charityData[], descriptionData[];
    int images[];
    Context context;

    public CharityListAdapter(Context ct, String charity[], String description[], int image[]) {
        context = ct;
        charityData = charity;
        descriptionData= description;
        images = image;

    }

    @NonNull
    @Override
    public CharityListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.data_row, parent, false);
        return new CharityListViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final CharityListViewHolder holder,final int position) {


        holder.titleText.setText(charityData[position]);
        holder.descText.setText(descriptionData[position]);
        holder.charityImage.setImageResource(images[position]);

        holder.charityLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(holder.charityLayout.isSelected()) {
                    holder.charityLayout.setSelected(false);
                    System.out.println("Set to false");

                } else if(!holder.charityLayout.isSelected()){
                    holder.charityLayout.setSelected(true);
                    System.out.println("Set to true");
                }

                if(holder.charityLayout.isSelected()) {
                    holder.whiteBox.setBackgroundResource(R.drawable.bluebox);

                    DonateSelection.enableNextButton();
                    System.out.println("Blue Box");
                }

                if(!holder.charityLayout.isSelected()) {
                    holder.whiteBox.setBackgroundResource(R.drawable.box);

                    System.out.println("White Box");
                }
            }
        });

    }

    @Override
    public int getItemCount() {                                                        
        return images.length;
    }

    public class CharityListViewHolder extends RecyclerView.ViewHolder {
        TextView titleText, descText;
        ImageView charityImage;

        RelativeLayout whiteBox;
        RelativeLayout charityLayout;

        public CharityListViewHolder(@NonNull View itemView) {
            super(itemView);

            titleText = itemView.findViewById(R.id.titleText);
            descText = itemView.findViewById(R.id.descText);
            charityImage = itemView.findViewById(R.id.charityImage);
            whiteBox = itemView.findViewById(R.id.whiteBox);
            charityLayout = itemView.findViewById(R.id.charityLayout);


        }

    }
}

Upvotes: 1

Views: 901

Answers (2)

Loremar Marabillas
Loremar Marabillas

Reputation: 833

Rather than remembering the layout/ViewHolder you selected, it's better to remember the selected position. In your adapter add:

private int positionSelected = -1;

-1 indicates none is selected.

And then, in your ViewHolder constructor:

        public CharityListViewHolder(@NonNull View itemView) {
            super(itemView);

            ....

            charityLayout = itemView.findViewById(R.id.charityLayout);

            charityLayour.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {                    
                    positionSelected = getAdapterPosition();
                    notifyDataSetChanged();
                }
            }); 
        }

In your onBindViewHolder you can set the background accordingly:

if (position == positionSelected) {
    // Set background for layout to indicate selected
} else {
    // Set background for layout to indicate unselected
}

Upvotes: 1

ZarNi Myo Sett Win
ZarNi Myo Sett Win

Reputation: 1453

This is because of how RecyclerView works. It recycles your view after it disappears from your screen. You should use if/else to maintain the right state of a view. Replace your onClick action with below code.

 holder.charityLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(holder.charityLayout.isSelected()) {
                        holder.charityLayout.setSelected(false);
                        System.out.println("Set to false");

                    } else {
                        holder.charityLayout.setSelected(true);
                        System.out.println("Set to true");
                    }

                    if(holder.charityLayout.isSelected()) {
                        holder.whiteBox.setBackgroundResource(R.drawable.bluebox);

                        DonateSelection.enableNextButton();
                        System.out.println("Blue Box");
                    }else{

                        holder.whiteBox.setBackgroundResource(R.drawable.box);

                        System.out.println("White Box");
                    }



                }
            });

Edited Here is raw code.But, I think that should work. You should add an array of check state that recycler is composed of. By default they all will be false. Then, check it onBindViewHolder(). When click, set boolean to true and call notifyDatasetChanged.

public class CharityListAdapter extends RecyclerView.Adapter<CharityListAdapter.CharityListViewHolder> {
    String charityData[], descriptionData[];
    int images[]; boolean checkState[];
    Context context;

    public CharityListAdapter(Context ct, String charity[], String description[], int image[],boolean checkState[]) {
        context = ct;
        charityData = charity;
        descriptionData= description;
        images = image;
    checkState=checkState;  
    }

    @NonNull
    @Override
    public CharityListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.data_row, parent, false);
        return new CharityListViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final CharityListViewHolder holder,final int position) {


        holder.titleText.setText(charityData[position]);
        holder.descText.setText(descriptionData[position]);
        holder.charityImage.setImageResource(images[position]);

    if(checkState[position]){
      holder.whiteBox.setBackgroundResource(R.drawable.bluebox);
          DonateSelection.enableNextButton();
    }else{
        holder.whiteBox.setBackgroundResource(R.drawable.box);
    }

        holder.charityLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
        if(checkState[position]){
            checkState[position]=false;
        }else{
            checkState[position]=true;
        }
                 notifyDataSetChanged();
            }
        });

    }

    @Override
    public int getItemCount() {                                                        
        return images.length;
    }

    public class CharityListViewHolder extends RecyclerView.ViewHolder {
        TextView titleText, descText;
        ImageView charityImage;

        RelativeLayout whiteBox;
        RelativeLayout charityLayout;

        public CharityListViewHolder(@NonNull View itemView) {
            super(itemView);

            titleText = itemView.findViewById(R.id.titleText);
            descText = itemView.findViewById(R.id.descText);
            charityImage = itemView.findViewById(R.id.charityImage);
            whiteBox = itemView.findViewById(R.id.whiteBox);
            charityLayout = itemView.findViewById(R.id.charityLayout);


        }

    }
}

Upvotes: 1

Related Questions