简体   繁体   中英

Changing color of a gradient drawable inside an itemview of a recycler-view

I'm building an app which is supposed to be visually intuitive to use. So, I have a gradient drawable in each item of a recycler view which is supposed to change its color on each click to a darker shade of color which it previously was. Eg from white to pink to red to maroon on clicking 4 times on a particular gradient drawable. I'm a beginner at this, can it be done?

Tried going through documentation nothing helped.

Here's my code of interface which holds the array of array of colors.

public interface ColorUtils {

 int[][] colorsArray=new int[][]{
       new int[]{R.color.red1, R.color.red2, R.color.red3, R.color.red4 },
       new int[]{R.color.blue1, R.color.blue2, R.color.blue3, R.color.blue4},
       new int[]{R.color.green1, R.color.green2, R.color.green3, R.color.green4},
       new int[]{R.color.yellow1, R.color.yellow2, R.color.yellow3, R.color.yellow4},
       new int[]{R.color.orange1, R.color.orange2, R.color.orange3, R.color.orange4},
       new int[]{R.color.brown1, R.color.brown2, R.color.brown3, R.color.brown4},
       new int[]{R.color.grey1, R.color.grey2, R.color.grey3, R.color.grey4}
 };

}

Here's what I am trying to do on onBindViewHolder method.

 int countOfClicks=0;
 @Override
public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, int i) {



    final GradientDrawable gd = (GradientDrawable) myViewHolder.image.getDrawable().getCurrent();
    final ImageView exclamation = myViewHolder.exclamation;
    final ImageView smily = myViewHolder.smily;

    gd.setColor(Color.WHITE);
    myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            countOfClicks++;
            switch (countOfClicks) {
                case 1:

                    gd.setColor(ColorUtils.colorsArray[myViewHolder.getAdapterPosition()][countOfClicks]);

                    break;
                case 2:

                    gd.setColor(ColorUtils.colorsArray[myViewHolder.getAdapterPosition()][countOfClicks]);

                    break;
                case 3:
                    gd.setColor(ColorUtils.colorsArray[myViewHolder.getAdapterPosition()][countOfClicks]);


                    break;

                default:

                    gd.setColor(ColorUtils.colorsArray[myViewHolder.getAdapterPosition()][countOfClicks]);
                    exclamation.setVisibility(View.GONE);
                    smily.setVisibility(View.VISIBLE);



            }
        }
    });

}

You keep in your Adapter a Hashmap, or a list with the values of the colors. Or you set on your myViewHolder.image as a tag the value like:

myViewHolder.image.setTag(ColorUtils.colorsArray[myViewHolder.getAdapterPosition()])

Then onClick you increment the clickcount, and do notifyDataSetChanged. in onBindViewHolder, you getTag() and based on the value you get, you set the correct color.

Why it doesn't work for you? 1. You do not call onClick notifyDataSetChanged. 2. If you would call notifyDataSetChanged, it goes through the onBindViewHolder and that causes it to turn white gd.setColor(Color.WHITE);

If you do instead of setColor(Colow.WHITE) the color based on TAG, it will work.

Another option would be to create a hashmap, of position and viewHolder:

var lstHolders: HashMap<Int, MyViewHolder> = HashMap()

onBindViewHolder you do:

  synchronized(lstHolders) {
      lstHolders.put(position, holder)
  }

And in your MyViewHolder you create a method like void changeColor() then onClickListener you get the viewholder based on your position and call changeColor(). This will change the color, without needing to call notidyDataSetChanged (aka will only modify that and not all views)

okay i solved it. i have 7 items within my recycler-view, made a separate int constant for each, initialised them to 0. Then, made a method that increments click-count by one and initialised it within on click method within on Bind viewholder method is triggered, it stores the click count now according to adapter position.

public int thisWasClicked(CustomCowAdapter.CowViewHolder cowViewHolder) {

    int position = cowViewHolder.getAdapterPosition();

    switch (position) {
        case 0:
            return setColorToDrawable(position, clicks1++);

        case 1:
            return setColorToDrawable(position, clicks2++);

        case 2:
            return setColorToDrawable(position, clicks3++);

        case 3:
            return setColorToDrawable(position, clicks4++);

        case 4:
            return setColorToDrawable(position, clicks5++);

        case 5:
            return setColorToDrawable(position, clicks6++);

        default:
            return setColorToDrawable(position, clicks7++);

    }


}


public int setColorToDrawable(int i, int clicks) {
    if (clicks < 4) return colorsArray[i][clicks];
    else return -1;
}

then in onBindViewHolder

cowViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int color = colorUtils.thisWasClicked(cowViewHolder);
            if (color > 0) {
                gd.setColor(ContextCompat.getColor(context, color));
            }
            if (color < 0) {
                gd.setColor(Color.WHITE);
                exclamation.setVisibility(View.GONE);
                smily.setVisibility(View.VISIBLE);

            }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM