web-dev-qa-db-fra.com

Changer la couleur de fond de l'élément sélectionné dans recyclerview

Comment modifier la couleur d'arrière-plan de la vue sélectionnée uniquement dans mon exemple d'affichage de recyclage? Seule la couleur d'arrière-plan de la vue d'élément cliquée doit être modifiée . soyez comme avant de choisir . voici mon code: 

Activité principale

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*/

        }
    }
}
32
c0der

Merci pour les gars de replay .. enfin j'ai eu la réponse ..

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"));
        }

    }

ici 'row_index' est défini sur '-1' initialement 

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);
        }
    }
70
c0der

Un moyen très simple d'y parvenir serait:

//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;
}

METTRE &AGRAVE; JOUR

La méthode ci-dessus peut ruiner certains attributs par défaut de l'itemView, dans mon cas, j'utilisais CardView, et le rayon de la carte était retiré au clic.

Meilleure solution:

//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));
            }
        });
}

MISE À JOUR 2 - IMPORTANT

la méthode onBindViewHolder est appelée plusieurs fois, et chaque fois que l'utilisateur fait défiler la vue de manière invisible et visible! Cela entraîne l'ajout de la même vue à la liste plusieurs fois, ce qui peut entraîner des problèmes et un léger retard du code. exécutions!

Pour résoudre ce problème, change

cardViewList.add(holder.cardView);

à

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

Je peux suggérer cette solution, que j'ai utilisée dans mon application. J'ai placé ce code de onTouchListener dans le constructeur de ma classe ViewHolder. itemView est l'argument du constructeur. Assurez-vous d'utiliser return false sur cette méthode car cette nécessité de travailler avec 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;
    }
});
4
Gulov Khurshed

Si vous utilisez Kotlin, c'est vraiment simple.

Dans votre classe RecyclerAdapter

userV.invalidateRecycler()

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

Dans votre fragment ou activité

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

Créer un fichier Drawable dans Drawable foloder

<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>

Et en fichier XML 

Android:background="@drawable/Drawable file"

Dans RecyclerView onBindViewHolder

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

Comme bouton bascule 

1
Joy

Ajoutez un écouteur de clic pour la vue d'élément dans .onBindViewHolder () de l'adaptateur de votre RecyclerView. récupère la position actuellement sélectionnée et change la couleur de .setBackground () pour l'élément sélectionné et l'élément en cours

0
Alex Shutov

J'ai réussi à faire cela à partir de mon activité où je suis en train de configurer mon RV et non de l'adaptateur

Si quelqu'un a besoin de faire quelque chose de similaire, voici le code

Dans ce cas, la couleur change sur un 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

Ma solution:

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 est null au début, puis pointe vers la dernière vue sélectionnée . Avec onClick, vous modifiez l'arrière-plan de la vue sélectionnée et redéfinissez l'arrière-plan de l'avant-dernière vue sélectionnée . Simple et fonctionnel.

0
Paolo

La manière la plus simple de mon côté consiste à ajouter une variable dans adapterPage en tant que dernière position cliquée.

dans onBindViewHolder collez ce code qui vérifie la dernière position stockée correspondant aux positions de chargement Constants est la classe dans laquelle je déclare mes variables globales

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