I have used RecyclerView for showing thumbnails in my Image Editing app.Each item of its comprises of a ImageView(thumbnail) and a textView.In my application I want to highlight only current selected thumbnail when clicked.Gone through all the related posts on SO but couldn't find any better solution.
My Adapter Class
public class FiltersAdapter extends RecyclerView.Adapter<FiltersAdapter.ViewHolder> { private Context mContext; private List<Type> mDataSet; private Uri selectedPhoto; public enum Type { Original, Grayscale, Sepia, Contrast, Invert, Pixel, Sketch, Swirl, Brightness, Vignette } public FiltersAdapter(Context context, List<Type> dataSet, Uri selectedPhoto) { mContext = context; mDataSet = dataSet; this.selectedPhoto = selectedPhoto; } @Override public FiltersAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(mContext).inflate(R.layout.list_item_layout, parent, false); return new ViewHolder(v); } @Override public void onBindViewHolder(FiltersAdapter.ViewHolder holder, int position) { switch (mDataSet.get(position)) { case Original: holder.image.setImageResource(R.drawable.no_filter); break; case Grayscale: Picasso.with(mContext) .load(R.drawable.no_filter) .transform(new GrayscaleTransformation()) .into(holder.image); break; case Sepia: Picasso.with(mContext) .load(R.drawable.no_filter) .transform(new SepiaFilterTransformation(mContext)) .into(holder.image); break; case Contrast: Picasso.with(mContext) .load(R.drawable.no_filter) .transform(new ContrastFilterTransformation(mContext, 2.0f)) .into(holder.image); break; case Invert: Picasso.with(mContext) .load(R.drawable.no_filter) .transform(new InvertFilterTransformation(mContext)) .into(holder.image); break; case Pixel: Picasso.with(mContext) .load(R.drawable.no_filter) .transform(new PixelationFilterTransformation(mContext, 20)) .into(holder.image); break; case Sketch: Picasso.with(mContext) .load(R.drawable.no_filter) .transform(new SketchFilterTransformation(mContext)) .into(holder.image); break; case Swirl: Picasso.with(mContext) .load(R.drawable.no_filter) .transform(new SwirlFilterTransformation(mContext, 0.5f, 1.0f, new PointF(0.5f, 0.5f))) .into(holder.image); break; case Brightness: Picasso.with(mContext) .load(R.drawable.no_filter) .transform(new BrightnessFilterTransformation(mContext, 0.5f)) .into(holder.image); break; case Vignette: Picasso.with(mContext) .load(R.drawable.no_filter) .transform(new VignetteFilterTransformation(mContext, new PointF(0.5f, 0.5f), new float[]{0.0f, 0.0f, 0.0f}, 0f, 0.75f)) .into(holder.image); break; default: holder.image.setImageResource(R.drawable.no_filter); break; } holder.title.setText(mDataSet.get(position).name()); } @Override public void onViewAttachedToWindow(ViewHolder holder) { super.onViewAttachedToWindow(holder); } @Override public int getItemCount() { return mDataSet.size(); } @Override public int getItemViewType(int position) { return position; } static class ViewHolder extends RecyclerView.ViewHolder { public ImageView image; public TextView title; ViewHolder(View itemView) { super(itemView); image = (ImageView) itemView.findViewById(R.id.thumbnailImage); title = (TextView) itemView.findViewById(R.id.title); } } }
Fragment Code
horizontalFilters = (RecyclerView) mView.findViewById(R.id.rvHorizontal); LinearLayoutManager horizontalLayoutManagaer = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false); horizontalFilters.setLayoutManager(horizontalLayoutManagaer); List<Type> dataSet = new ArrayList<>(); dataSet.add(Type.Original); dataSet.add(Type.Grayscale); dataSet.add(Type.Sepia); dataSet.add(Type.Contrast); dataSet.add(Type.Invert); dataSet.add(Type.Pixel); dataSet.add(Type.Sketch); dataSet.add(Type.Swirl); dataSet.add(Type.Brightness); dataSet.add(Type.Vignette); horizontalFilters.setAdapter(new FiltersAdapter(act, dataSet, selectedPhotoUri)); horizontalFilters.addOnItemTouchListener(new RecyclerClick(act, horizontalFilters, new RecyclerClickListener() { @Override public void onClick(View view, int position) { switch (position){ case 0: photo.setImageDrawable(drawable); break; case 1: Picasso.with(act) .load(selectedPhotoUri) .transform(new GrayscaleTransformation()) .into(photo); break; case 2: Picasso.with(act) .load(selectedPhotoUri) .transform(new SepiaFilterTransformation(act)) .into(photo); break; case 3: Picasso.with(act) .load(selectedPhotoUri) .transform(new ContrastFilterTransformation(act, 2.0f)) .into(photo); break; case 4: Picasso.with(act) .load(selectedPhotoUri) .transform(new InvertFilterTransformation(act)) .into(photo); break; case 5: Picasso.with(act) .load(selectedPhotoUri) .transform(new PixelationFilterTransformation(act, 20)) .into(photo); break; case 6: Picasso.with(act) .load(selectedPhotoUri) .transform(new SketchFilterTransformation(act)) .into(photo); break; case 7: Picasso.with(act) .load(selectedPhotoUri) .transform(new SwirlFilterTransformation(act, 0.5f, 1.0f, new PointF(0.5f, 0.5f))) .into(photo); break; case 8: Picasso.with(act) .load(selectedPhotoUri) .transform(new BrightnessFilterTransformation(act, 0.5f)) .into(photo); break; case 9: Picasso.with(act) .load(selectedPhotoUri) .transform(new VignetteFilterTransformation(act, new PointF(0.5f, 0.5f), new float[]{0.0f, 0.0f, 0.0f}, 0f, 0.75f)) .into(photo); break; default: photo.setImageDrawable(drawable); break; } } @Override public void onLongClick(View view, int position) { } })); }
It's more efficient by default, the layout is separated and we have more possibilities over the data set inside the adapter. The ViewHolder pattern allows us to make our list scrolling act smoothly.
Just add this below line in bindView
holder.itemView.setBackgroundColor(Color.parseColor("#000000"));
will work for you.
if you want to highlight a selected item just do like below
set it global
int selectedPosition=-1;
inside onBindViewHolder-
public void onBindViewHolder(FiltersAdapter.ViewHolder holder, int position) { if(selectedPosition==position) holder.itemView.setBackgroundColor(Color.parseColor("#000000")); else holder.itemView.setBackgroundColor(Color.parseColor("#ffffff")); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { selectedPosition=position; notifyDataSetChanged(); } }); }
===========================================================
Above code works fine as per old school methodology but here is the updated version which might help you:
Kotlin-
If you want to highlight a selected item just follow:
var selectedPosition = -1; //make it global
inside onBindViewHolder-
override fun onBindViewHolder(holder: FiltersAdapter.ViewHolder, position: Int) { if (selectedPosition == position) holder.itemView.setBackgroundColor(Color.parseColor("#000000")) else holder.itemView.setBackgroundColor(Color.parseColor("#ffffff")) }
And create inner class ViewHolder which implements View.OnClickListener
and override the onClick
function.
override fun onClick(v: View) { when (v.id) { R.id.parent-> { selectedPosition = adapterPosition; notifyDataSetChanged(); } } }
Cheers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With