web-dev-qa-db-fra.com

Sélecteur de fond dans RecyclerView Item

J'utilise la RecyclerView comme ci-dessous:

<Android.support.v7.widget.RecyclerView
    Android:id="@+id/list"
    Android:layout_width="320dp"
    Android:layout_height="match_parent"/>

et mon article de liste:

<LinearLayout  Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:background="@drawable/selector_medium_high">
    <com.basf.suvinil.crie.ui.common.widget.CircleView
        Android:id="@+id/circle"
        Android:layout_width="22dp"
        Android:layout_height="22dp"/>
    <TextView
        Android:id="@+id/label"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:minHeight="57.5dp"/>
</LinearLayout>

voir en détail cette partie Android:background="@drawable/selector_medium_high" c'est un sélecteur normal:

<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:drawable="@color/background_high" Android:state_activated="true"/>
    <item Android:drawable="@color/background_high" Android:state_pressed="true"/>
    <item Android:drawable="@color/background_high" Android:state_checked="true"/>
    <item Android:drawable="@color/background_high" Android:state_focused="true"/>
    <item Android:drawable="@color/background_medium"/>
</selector>

mais quand je lance ce code, je n'ai aucun changement de couleur d'arrière-plan quand je touche le rang ... 

38
ademar111190

Définissez clickable, focusable, focusableInTouchMode à true dans tous les éléments de RecyclerView "liste".

50
Ahmed Ghonim

Si rien de tout cela ne fonctionne pour vous, comme ce ne l'a pas été pour moi, utilisez ce code:

Android:foreground="?android:attr/selectableItemBackground"

L'astuce est dans l'attribut Android:foreground ...

12
NixSam

Ajouter Android:background="?android:attr/selectableItemBackground" à my_list_item.xml ' root layout semble fonctionner pour moi (en supposant que vous souhaitiez la couleur de sélection par défaut).

Assurez-vous également que le Android:layout_width de la mise en page racine est match_parent au lieu de wrap_content pour vous assurer que toute la ligne est sélectionnable.

12
Lawrr

Malheureusement, utiliser des vues focalisables pour simuler la sélection d'éléments est pas une bonne solution} _ parce que

  • La mise au point est perdue lorsque notifyDataSetChanged est appelé
  • La mise au point est problématique lorsque les points de vue des enfants sont focalisables

J'ai écrit une classe d'adaptateur de base pour gérer automatiquement la sélection d'éléments avec RecyclerView. Il vous suffit d’en dériver votre adaptateur et d’utiliser des listes d’états dessinables avec state_selected, comme vous le feriez avec une vue liste. 

J'ai un Blog Post Ici à ce sujet, mais voici le code:

public abstract class TrackSelectionAdapter<VH extends TrackSelectionAdapter.ViewHolder> extends RecyclerView.Adapter<VH> {
    // Start with first item selected
    private int focusedItem = 0;

    @Override
    public void onAttachedToRecyclerView(final RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);

        // Handle key up and key down and attempt to move selection
        recyclerView.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                RecyclerView.LayoutManager lm = recyclerView.getLayoutManager();

                // Return false if scrolled to the bounds and allow focus to move off the list
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
                        return tryMoveSelection(lm, 1);
                    } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
                        return tryMoveSelection(lm, -1);
                    }
                }

                return false;
            }
        });
    }

    private boolean tryMoveSelection(RecyclerView.LayoutManager lm, int direction) {
        int tryFocusItem = focusedItem + direction;

        // If still within valid bounds, move the selection, notify to redraw, and scroll
        if (tryFocusItem >= 0 && tryFocusItem < getItemCount()) {
            notifyItemChanged(focusedItem);
            focusedItem = tryFocusItem;
            notifyItemChanged(focusedItem);
            lm.scrollToPosition(focusedItem);
            return true;
        }

        return false;
    }

    @Override
    public void onBindViewHolder(VH viewHolder, int i) {
        // Set selected state; use a state list drawable to style the view
        viewHolder.itemView.setSelected(focusedItem == i);
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        public ViewHolder(View itemView) {
            super(itemView);

            // Handle item click and set the selection
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // Redraw the old selection and the new
                    notifyItemChanged(focusedItem);
                    focusedItem = mRecyclerView.getChildPosition(v);
                    notifyItemChanged(focusedItem);
                }
            });
        }
    }
} 
6
Greg Ennis
    viewHolder.mRlPrince.setOnTouchListener(new View.OnTouchListener() {
        @Override public boolean onTouch(View v, MotionEvent event) {

            if (event.getAction()==MotionEvent.ACTION_DOWN){
                viewHolder.mRlPrince.setBackgroundColor(Color.parseColor("#f8f8f8"));
            }if (event.getAction()==MotionEvent.ACTION_UP){
                viewHolder.mRlPrince.setBackgroundColor(Color.WHITE);
            }

            return false;
        }
    });
4
jingyuan iu

Ajoutez cet attribut ci-dessous dans votre élément "my_list_item.xml"
Android:descendantFocusability="blocksDescendants" Cela fonctionne pour moi!

3
Rajiv Manivannan

Vous devez définir Android:clickable="true" dans l'élément xml et si vous avez plus de sélecteurs dans certaines vues de votre vue, vous devez définir Android:duplicateParentState="true" ici aussi. Cela fonctionne sur les apis en nid d'abeille.

1
Bruno Pinto

sur votre dessin ou votre fichier xml, placez simplement les lignes suivantes.

Android:clickable="true"
Android:focusable="true"
Android:background="?android:attr/activatedBackgroundIndicator"
0
Juboraj Sarker

Comme beaucoup d'autres ont répondu, le seul moyen est de combiner des sélecteurs et de nouvelles classes pour garder une trace de la sélection, mais il vaut mieux déléguer ce calcul à l'adaptateur. La bibliothèque FlexibleAdapter assure le suivi des sélections pour vous, le changement de configuration est également compatible.

La couleur d'arrière-plan avec ondulation peut maintenant être réalisée sans partie XML, mais dans le code pour gérer les données dynamiques.

Enfin, vous pouvez utiliser de nombreuses fonctionnalités avec la même bibliothèque. La sélection est une toute petite fonctionnalité de base.

Veuillez consulter la description, les pages Wiki et des exemples complets: https://github.com/davideas/FlexibleAdapter

0
Davideas