seleccion - selectable recyclerview android
Selector de fondo en RecyclerVer artÃculo (9)
Estoy usando el RecyclerView
como a continuación:
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="320dp"
android:layout_height="match_parent"/>
y mi elemento de la lista:
<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>
ver en detalle esta parte de android:background="@drawable/selector_medium_high"
es un selector 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>
pero cuando ejecuto este código, no tengo cambios en el color de fondo cuando toco la fila ...
Agregar android:background="?android:attr/selectableItemBackground"
al diseño de raíz de my_list_item.xml
parece funcionar para mí (suponiendo que desee el color de selección predeterminado).
También asegúrese de que el diseño de la raíz de android:layout_width
sea match_parent
lugar de wrap_content
para garantizar que toda la fila sea seleccionable.
Agregar:
android:background="?android:attr/selectableItemBackground"
en item.xml
Agregue este atributo a continuación en su artículo "my_list_item.xml"
android:descendantFocusability="blocksDescendants"
Esto funciona para mí!
Como muchos otros respondieron, la única forma es combinar selectores y nuevas clases para realizar un seguimiento de la selección, pero es mejor delegar este cálculo en el adaptador. La biblioteca FlexibleAdapter realiza un seguimiento de las selecciones, el cambio de configuración también es compatible.
El color de fondo con rizado ahora se puede hacer sin parte XML, pero en el código para administrar datos dinámicos.
Finalmente, puede usar muchas características con la misma biblioteca, la selección es una pequeña característica básica que puede tener.
Por favor, eche un vistazo a la descripción, las páginas Wiki y el ejemplo de trabajo completo: https://github.com/davideas/FlexibleAdapter
Desgraciadamente, utilizar vistas enfocables para simular la selección de elementos no es una buena solución porque:
- El foco se pierde cuando se llama a
notifyDataSetChanged
- El enfoque es problemático cuando las vistas de los niños son enfocables
Escribí una clase de adaptador base para manejar automáticamente la selección de elementos con un RecyclerView. Simplemente obtenga su adaptador y use listas de estado dibujables con state_selected, como lo haría con una vista de lista.
Tengo una publicación en el blog sobre esto, pero aquí está el código:
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);
}
});
}
}
}
Establezca clickable
focusable
, focusableInTouchMode
y focusableInTouchMode
en true
en todos los elementos de la "lista" de RecyclerView
.
Necesitas configurar android:clickable="true"
en el elemento xml, y si tienes más selectores en alguna vista dentro de tu vista, necesitas configurar android:duplicateParentState="true"
allí también. Eso funciona en apis previas al panal.
Si nada de esto funciona para usted, como no lo hizo para mí, use este código:
android:foreground="?android:attr/selectableItemBackground"
El truco está en android:foreground
atributo de android:foreground
...
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;
}
});