0

I created a simple RecyclerView and a CardView in it. In CardView there are ImageView and TextView. So I'm get the url of the image and load it using Picasso. Everything worked well before using Palette API. So I want to get the color from image and set it to CardView and TextView.

Here's my RecyclerView.Adapter

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {

    private List<String> imagesUrl;
    private List<String> imageDescription;

    RecyclerAdapter(List<String> imagesUrl, List<String> imageDescription) {
        this.imagesUrl = imagesUrl;
        this.imageDescription = imageDescription;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) {
        View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, int position) {
        myViewHolder.textView.setText(imageDescription.get(position));
        Picasso.get()
                .load(imagesUrl.get(position))
                .into(new Target() {
                    @Override
                    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                        myViewHolder.imageView.setImageBitmap(bitmap);
                        myViewHolder.getPalette();
                    }

                    @Override
                    public void onBitmapFailed(Exception e, Drawable errorDrawable) {
                        myViewHolder.imageView.setImageResource(R.drawable.error);
                    }

                    @Override
                    public void onPrepareLoad(Drawable placeHolderDrawable) {
                        myViewHolder.imageView.setImageResource(R.drawable.placeholder);
                    }
                });
    }

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

    class MyViewHolder extends RecyclerView.ViewHolder {

        private ImageView imageView;
        private TextView textView;
        private CardView cardView;

        MyViewHolder(@NonNull View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.imageView);
            textView = itemView.findViewById(R.id.textView);
            cardView = itemView.findViewById(R.id.cardView);
        }

        private void getPalette() {
            Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
            Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
                @Override
                public void onGenerated(@Nullable Palette palette) {
                    //assert palette != null;
                    Palette.Swatch swatch = palette.getVibrantSwatch();
                    //assert swatch != null;
                    textView.setTextColor(swatch.getBodyTextColor());
                    cardView.setCardBackgroundColor(swatch.getRgb());
                }
            });
        }
    }
}

Every time it shows the placeholder image. When I'm doing debug, it works. So what's the problem?

Zoe
  • 27,060
  • 21
  • 118
  • 148
Hayk Mkrtchyan
  • 2,835
  • 3
  • 19
  • 61

1 Answers1

0

So problem is not in Palette API. Problem is that target is being garbage collected.So the solution is to implement it on an object or store it in a field and set it as tag to our ImageView.

Here. That's now working.

@Override
public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, int position) {
    myViewHolder.textView.setText(imageDescription.get(position));
    Target target = new Target() {
        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
            myViewHolder.imageView.setImageBitmap(bitmap);
            myViewHolder.getPalette();
        }

        @Override
        public void onBitmapFailed(Drawable errorDrawable) {
            myViewHolder.imageView.setImageResource(R.drawable.error);
        }

        @Override
        public void onPrepareLoad(Drawable placeHolderDrawable) {
            myViewHolder.imageView.setImageResource(R.drawable.placeholder);
        }
    };

    Picasso.with(context)
            .load(imagesUrl.get(position))
            .into(target);

    myViewHolder.imageView.setTag(target);
}

I think this will help anyone someday))) Thank you

Hayk Mkrtchyan
  • 2,835
  • 3
  • 19
  • 61