画像編集アプリでサムネイルを表示するためにRecyclerViewを使用しました。その各アイテムはImageView(サムネイル)とtextViewで構成されています。アプリケーションでは、クリックすると現在の選択のみを強調表示サムネイルします。 SOのすべての関連投稿が、より良い解決策を見つけることができませんでした。
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);
}
}
}
フラグメントコード
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) {
}
}));
}
BindViewの以下の行を追加してください
holder.itemView.setBackgroundColor(Color.parseColor("#000000"));
あなたのために働くでしょう。
選択したアイテムを強調表示する場合は、以下のようにします
グローバルに設定する
int selectedPosition=-1;
内部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();
}
});
}
バックグラウンドセレクタを使用し、recyclerviewアイテムのレイアウトxmlでAndroid:backgroundプロパティに設定します
background_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:state_pressed="false" Android:state_selected="true">
<shape>
<solid Android:color="@color/lightPrimaryColor" />
</shape>
</item>
<item Android:state_selected="false">
<shape>
<solid Android:color="@Android:color/transparent" />
</shape>
</item>
</selector>
recyclerview_item.xml(Android:backgroundプロパティでbackground_selectorが設定されています)
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="@drawable/background_selector"
Android:orientation="vertical"
Android:paddingBottom="8dp"
Android:paddingLeft="16dp"
Android:paddingRight="16dp"
Android:paddingTop="8dp">
そして、クリックイベントを取得する場所は、表示機能で選択されたとおりに設定できます
view.setSelected(true)
選択したアイテムの位置を保存して、アイテムの選択/選択解除を行う場合のロジックを実装する必要があります
単に使用する場合があります:
Android:background="?attr/selectableItemBackground"
アイテムxmlのルート要素ですか?
フラグのために列挙型を最初にクラスに更新します
public class Type {
public int type; // 0-Original,1-Grayscale,2-Sepia.... same as enum
public int selected;
}
今アダプターで
@Override
public void onBindViewHolder(FiltersAdapter.ViewHolder holder, int position) {
int typeOfItem = mDataSet.get(position).type
switch (mDataSet.get(position)) {
case 0:
holder.image.setImageResource(R.drawable.no_filter);
break;
case 1:
Picasso.with(mContext)
.load(R.drawable.no_filter)
.transform(new GrayscaleTransformation())
.into(holder.image);
break;
case 2:
Picasso.with(mContext)
.load(R.drawable.no_filter)
.transform(new SepiaFilterTransformation(mContext))
.into(holder.image);
break;
case 3:
Picasso.with(mContext)
.load(R.drawable.no_filter)
.transform(new ContrastFilterTransformation(mContext, 2.0f))
.into(holder.image);
break;
case 4:
Picasso.with(mContext)
.load(R.drawable.no_filter)
.transform(new InvertFilterTransformation(mContext))
.into(holder.image);
break;
case 5:
Picasso.with(mContext)
.load(R.drawable.no_filter)
.transform(new PixelationFilterTransformation(mContext, 20))
.into(holder.image);
break;
case 6:
Picasso.with(mContext)
.load(R.drawable.no_filter)
.transform(new SketchFilterTransformation(mContext))
.into(holder.image);
break;
case 7:
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 8:
Picasso.with(mContext)
.load(R.drawable.no_filter)
.transform(new BrightnessFilterTransformation(mContext, 0.5f))
.into(holder.image);
break;
case 9:
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());
if(mDataSet.get(position).selected == 0){
holder.title.setTypeface(null, Typeface.BOLD);
} else {
holder.title.setTypeface(null,Typeface.NORMAL);
}
}
すべてのクリックまたは選択でリストを更新するのではなく、アダプターのnotifydatasetChanged()を呼び出します