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 ...
Définissez clickable
, focusable
, focusableInTouchMode
à true
dans tous les éléments de RecyclerView
"liste".
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
...
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.
Malheureusement, utiliser des vues focalisables pour simuler la sélection d'éléments est pas une bonne solution} _ parce que
notifyDataSetChanged
est appelé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);
}
});
}
}
}
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;
}
});
Ajoutez cet attribut ci-dessous dans votre élément "my_list_item.xml"Android:descendantFocusability="blocksDescendants"
Cela fonctionne pour moi!
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.
sur votre dessin ou votre fichier xml, placez simplement les lignes suivantes.
Android:clickable="true"
Android:focusable="true"
Android:background="?android:attr/activatedBackgroundIndicator"
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