83 votes

Changement de la couleur d'arrière-plan de l'élément sélectionné dans la vue recyclée

Comment modifier la couleur d'arrière-plan d'une seule vue sélectionnée dans mon exemple de vue de recyclage ? Seule la couleur d'arrière-plan de la vue de l'élément cliqué doit être modifiée. Seul un élément sélectionné doit être affiché avec un changement de couleur de fond à la fois et le reste doit être comme avant la sélection. 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*/

        }
    }
}

0 votes

Changer @color pour @drawable/shapecolored ajouter forme

181voto

c0der Points 870

Finalement, 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 comme '-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);
        }
    }

1 votes

Le code fonctionne parfaitement mais j'ai une erreur lorsque je change la couleur du texte, par exemple (0 index texte (bleu) 1 index texte (noir)) lorsque le noir devient bleu, pouvez-vous m'aider ?

1 votes

Ici comment changer la couleur des éléments non sélectionnés ?

3 votes

Je ne pense pas que ce soit une très bonne idée de créer un nouveau onclicklistener à chaque fois dans le onbindViewholder.

13voto

Hanzyusuf Points 81

Un moyen 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;
}

Mise à JOUR

La méthode ci-dessus peut ruiner certains attributs par défaut de l'itemView, dans mon cas, j'ai été en utilisant CardView, et le rayon de l'angle de la carte se retirer sur cliquez sur.

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

onBindViewHolder méthode est appelée plusieurs fois, et aussi à chaque fois que l'utilisateur fait défiler la vue hors de la vue et à l'arrière en vue! Cela entraînera le même point de vue à être ajouté à la liste plusieurs fois ce qui peut entraîner des problèmes et retard mineur dans le code exécutions!

Pour résoudre ce problème, changement

cardViewList.add(holder.cardView);

pour

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

6voto

Gulov Khurshed Points 41

Je peux vous proposer cette solution, que j'ai utilisée dans mon application. I itemView est l'argument du constructeur. Veillez à utiliser retournez à la case départ sur cette méthode parce que ce besoin pour travailler 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;
    }
});

1 votes

Aide à maintenir l'état de pression.

5voto

Joy Points 121

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 dans le fichier xml

android:background="@drawable/Drawable file"

Dans le RecyclerView onBindViewHolder

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

Bouton à bascule "Like

0 votes

Qu'est-ce que ça veut dire ? Anvi.

2 votes

@Joy il change la couleur seulement pour un moment bries.

2voto

Rudrik Panchal Points 11

Si vous utilisez Kotlin, c'est très 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)
            }
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X