web-dev-qa-db-ja.com

RecyclerViewで選択したアイテムを強調表示する方法

画像編集アプリでサムネイルを表示するために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) {

        }
    }));
}
15
musica

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();

            }
        });
}
55
Amit Bhati

バックグラウンドセレクタを使用し、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)

選択したアイテムの位置を保存して、アイテムの選択/選択解除を行う場合のロジックを実装する必要があります

6
Monu Surana

単に使用する場合があります:

Android:background="?attr/selectableItemBackground"

アイテムxmlのルート要素ですか?

1
Nordknight

フラグのために列挙型を最初にクラスに更新します

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()を呼び出します

0
Rahul