web-dev-qa-db-ja.com

recyclerviewで選択したアイテムの背景色を変更する

リサイクルビューの例で選択したビューのみの背景色を変更する方法は?クリックしたアイテムビューの背景色のみを変更する必要があります。一度に背景色を変更して選択したアイテムを1つだけ表示する必要があり、残りは選択する前と同じにする必要があります。ここに私のコードがあります:

MainActivity

public class MainActivity extends AppCompatActivity {
RecyclerView rv1;
    private  final String Android_versions[]={
                "Donut",
                "Eclair",
                "Froyo",
                "Gingerbread",
                "Honeycomb",
                "Ice cream sandwich",
                "Jelly bean",
                "KitKat",
                "Lollipop",
                "Marshmallow"
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();
    }

    private  void initViews(){
        rv1=(RecyclerView)findViewById(R.id.recyclerView1);
        rv1.setHasFixedSize(true);
        RecyclerView.LayoutManager layoutManager=new LinearLayoutManager(getApplicationContext());
        rv1.setLayoutManager(layoutManager);

        RecyclerDataAdapter rda=new RecyclerDataAdapter(rv1,getApplicationContext(),Android_versions);
        rv1.setAdapter(rda);
    }
}

RecyclerDataadapter

public class RecyclerDataAdapter extends RecyclerView.Adapter<RecyclerDataAdapter.ViewHolder> {

private String Android_versionnames[];
    private Context context1;

    private RecyclerView mRecyclerView;


    public RecyclerDataAdapter(RecyclerView recylcerView,Context context,String Android_versionnames[]){
        this.Android_versionnames=Android_versionnames;
        this.context1=context;
mRecyclerView=recylcerView;
        setHasStableIds(true);
        System.out.println("Inside dataadapter,Android names : \n ");
        for(int i=0;i<Android_versionnames.length;i++){
            System.out.println("\n"+Android_versionnames[i]);
        }
    }


    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout,parent,false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        holder.tv1.setText(Android_versionnames[position]);
    }


    @Override
    public int getItemCount() {
        return Android_versionnames.length;
    }


    public class ViewHolder extends RecyclerView.ViewHolder {
        private TextView tv1;
        LinearLayout row_linearlayout;
        RecyclerView rv2;

        public ViewHolder(final View itemView) {
            super(itemView);
            tv1=(TextView)itemView.findViewById(R.id.txtView1);
            row_linearlayout=(LinearLayout)itemView.findViewById(R.id.row_linrLayout);
            rv2=(RecyclerView)itemView.findViewById(R.id.recyclerView1);
            /*itemView.setBackgroundColor(0x00000000);//to transparent*/

        }
    }
}
41
c0der

最後に、私は答えを得ました。

public void onBindViewHolder(final ViewHolder holder, final int position) {
        holder.tv1.setText(Android_versionnames[position]);

        holder.row_linearlayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                row_index=position;
                notifyDataSetChanged();
            }
        });
        if(row_index==position){
            holder.row_linearlayout.setBackgroundColor(Color.parseColor("#567845"));
            holder.tv1.setTextColor(Color.parseColor("#ffffff"));
        }
        else
        {
            holder.row_linearlayout.setBackgroundColor(Color.parseColor("#ffffff"));
            holder.tv1.setTextColor(Color.parseColor("#000000"));
        }

    }

ここで、「row_index」は最初は「-1」に設定されています

public class ViewHolder extends RecyclerView.ViewHolder {
        private TextView tv1;
        LinearLayout row_linearlayout;
        RecyclerView rv2;

        public ViewHolder(final View itemView) {
            super(itemView);
            tv1=(TextView)itemView.findViewById(R.id.txtView1);
            row_linearlayout=(LinearLayout)itemView.findViewById(R.id.row_linrLayout);
            rv2=(RecyclerView)itemView.findViewById(R.id.recyclerView1);
        }
    }
89
c0der

これを達成するための本当に簡単な方法は次のとおりです:

//instance variable
List<View>itemViewList = new ArrayList<>();

//OnCreateViewHolderMethod
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {    
    final View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_row, parent, false);
    final MyViewHolder myViewHolder = new MyViewHolder(itemView);

    itemViewList.add(itemView); //to add all the 'list row item' views

    //Set on click listener for each item view
    itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            for(View tempItemView : itemViewList) {
                /** navigate through all the itemViews and change color
                of selected view to colorSelected and rest of the views to colorDefault **/
                if(itemViewList.get(myViewHolder.getAdapterPosition()) == tempItemView) {
                    tempItemView.setBackgroundResource(R.color.colorSelected);
                }
                else{
                    tempItemView.setBackgroundResource(R.color.colorDefault);
                }
            }
        }
    });
    return myViewHolder;
}

UPDATE

上記の方法は、itemViewのデフォルトの属性を台無しにする可能性があります。私の場合、私はCardViewを使用しており、クリックするとカードの角の半径が削除されていました。

より良い解決策:

//instance variable
List<CardView>cardViewList = new ArrayList<>();

public class MyViewHolder extends RecyclerView.ViewHolder {
        CardView cardView; //THIS IS MY ROOT VIEW
        ...

        public MyViewHolder(View view) {
            super(view);
            cardView = view.findViewById(R.id.row_item_card);
            ...
        }
}

@Override
    public void onBindViewHolder(final MyViewHolder holder, int position) {
        final OurLocationObject locationObject = locationsList.get(position);
        ...

        cardViewList.add(holder.cardView); //add all the cards to this list

        holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //All card color is set to colorDefault
                for(CardView cardView : cardViewList){
                cardView.setCardBackgroundColor(context.getResources().getColor(R.color.colorDefault));
                }
                //The selected card is set to colorSelected
                holder.cardView.setCardBackgroundColor(context.getResources().getColor(R.color.colorSelected));
            }
        });
}

更新2-重要

onBindViewHolderメソッドは複数回呼び出されます。また、ユーザーがビューをスクロールして見えなくなったり、見えなくなったりするたびに呼び出されます。これにより、同じビューがリストに複数回追加され、問題が発生し、コードの実行にわずかな遅延が発生する可能性があります!

これを修正するには、change

cardViewList.add(holder.cardView);

to

if (!cardViewList.contains(holder.cardView)) {
    cardViewList.add(holder.cardView);
}
6
Hanzyusuf

アプリで使用したこのソリューションを提案できます。このonTouchListenerのコードをViewHolderクラスのコンストラクターに配置しました。 itemViewはコンストラクターの引数です。 必ずこのメソッドでreturn falseを使用してください OnClickListenerを動作させる必要があるため

itemView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN)
        {
            v.setBackgroundColor(Color.parseColor("#f0f0f0"));
        }
        if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL)
        {
            v.setBackgroundColor(Color.TRANSPARENT);
        }
        return false;
    }
});
5
Gulov Khurshed

Kotlinを使用する場合、それは本当に簡単です。

ご使用のRecyclerAdapterクラス

userV.invalidateRecycler()

holder.card_User.setCardBackgroundColor(Color.parseColor("#3eb1ae").withAlpha(60))

フラグメントまたはアクティビティ内

 override fun invalidateRecycler() {
    if (v1.recyclerCompanies.childCount > 0) {
        v1.recyclerCompanies.childrenRecursiveSequence().iterator().forEach { card ->
            if (card is CardView) {
                card.setCardBackgroundColor(Color.WHITE)
            }
        }
    }
}
2
Rudrik Panchal

Drawable FoloderでDrawableファイルを作成する

<item Android:drawable="@color/SelectedColor" Android:state_pressed="true"></item>
<item Android:drawable="@color/SelectedColor" Android:state_selected="true"></item>
<item Android:drawable="@color/DefultColor"></item>

そして、xmlファイルで

Android:background="@drawable/Drawable file"

RecyclerView onBindViewHolderで

holder.button.setSelected(holder.button.isSelected()?true:false);

トグルボタンのように

2
Joy

私の解決策:

public static class SimpleItemRecyclerViewAdapter
        extends RecyclerView.Adapter<SimpleItemRecyclerViewAdapter.ViewHolder> {

    private final MainActivity mParentActivity;
    private final List<DummyContent.DummyItem> mValues;
    private final boolean mTwoPane;
    private static int lastClickedPosition=-1;
    **private static View viewOld=null;**
    private final View.OnClickListener mOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            DummyContent.DummyItem item = (DummyContent.DummyItem) view.getTag();
            if (mTwoPane) {
                Bundle arguments = new Bundle();
                arguments.putString(ItemDetailFragment.ARG_ITEM_ID, item.id);
                ItemDetailFragment fragment = new ItemDetailFragment();
                fragment.setArguments(arguments);
                mParentActivity.getSupportFragmentManager().beginTransaction()
                        .replace(R.id.item_detail_container, fragment)
                        .commit();
            } else {
                Context context = view.getContext();
                Intent intent = new Intent(context, ItemDetailActivity.class);
                intent.putExtra(ItemDetailFragment.ARG_ITEM_ID, item.id);

                context.startActivity(intent);
            }

            **view.setBackgroundColor(mParentActivity.getResources().getColor(R.color.SelectedColor));
            if(viewOld!=null)
                viewOld.setBackgroundColor(mParentActivity.getResources().getColor(R.color.DefaultColor));
            viewOld=view;**
        }
    };

viewOldは先頭がnullで、最後に選択したビューを指します。 onClickを使用すると、選択したビューの背景を変更し、選択した最後から2番目のビューの背景を再定義します。シンプルで機能的。

1
Paolo

ご使用のRecyclerViewのアダプターの.onBindViewHolder()にアイテムビューのクリックリスナーを追加します。現在選択されている位置を取得し、以前に選択された現在のアイテムの.setBackground()によって色を変更します

0
Alex Shutov

アダプタからではなく、Rvを設定しているアクティビティからこれを行うことができました

誰かが似たようなことをする必要がある場合、ここにコードがあります

この場合、logClickの色が変わります

           @Override
        public void onLongClick(View view, int position) {
            Toast.makeText(UltimasConsultasActivity.this, "Item agregado a la lista de mails",
                    Toast.LENGTH_SHORT).show();

            sendMultipleMails.setVisibility(View.VISIBLE);
            valueEmail.setVisibility(View.VISIBLE);
            itemsSeleccionados.setVisibility(View.VISIBLE);

            listaEmails.add(superListItems.get(position));
            listaItems ="";
            NameOfyourRecyclerInActivity.findViewHolderForAdapterPosition(position).NameOfYourViewInTheViewholder.setBackgroundColor((Color.parseColor("#336F0D")));

            for(int itemsSelect = 0; itemsSelect <= listaEmails.size() -1; itemsSelect++){

             listaItems  +=  "*"+listaEmails.get(itemsSelect).getDescripcion() + "\n";
            }

            itemsSeleccionados.setText("Items Seleccionados : "+  "\n" + listaItems);


        }


    }));
0
JoaquinAlvarez

このようになった

public void onClick(View v){
        v.findViewById(R.id.textView).setBackgroundColor(R.drawable.selector_row);
 }

ありがとう

0
MindRoasterMir

Drawableフォルダーにセレクターを作成します。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android"> 
<item Android:state_pressed="true">
   <shape>
         <solid Android:color="@color/blue" />
   </shape>
</item>

<item Android:state_pressed="false">
    <shape>
       <solid Android:color="@Android:color/transparent" />
    </shape>
</item>
</selector>

プロパティをxmlに追加します(RecyclerViewを宣言する場所):

Android:background="@drawable/selector"
0
GiuseppeLabanca

一番簡単な方法は、adapterPageに最後にクリックした位置として変数を追加することです。

onBindViewHolderでは、ロード位置と一致する最後に保存された位置をチェックするこのコードを貼り付けます定数は、グローバル変数を宣言するクラスです

if(Constants.LAST_SELECTED_POSITION_SINGLE_PRODUCT == position) {

    //change the view background here
    holder.colorVariantThumb.setBackgroundResource(R.drawable.selected_background);
}

//on view click you store the position value and notifyItemRangeChanged will 
// call the onBindViewHolder and will check the condition

holder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view){
        Constants.LAST_SELECTED_POSITION_SINGLE_PRODUCT=position;
        notifyItemRangeChanged(0, mColorVariants.size());
    } 
});
0
Rahul