Selector de Fondo en el elemento RecyclerView


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 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 corro este código, no tengo cambios en el color de fondo cuando toco la fila....

Author: ademar111190, 2014-08-20

10 answers

Conjunto clickable, focusable, focusableInTouchMode a true en todos los elementos de RecyclerView "lista".

 48
Author: Ahmed Ghonim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-09 22:38:15

Añadir:

android:background="?android:attr/selectableItemBackground"

En item.xml

 28
Author: 100rbh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-28 11:10:47

Agregar android:background="?android:attr/selectableItemBackground" al diseño raíz my_list_item.xml parece funcionar para mí (suponiendo que desee el color de selección predeterminado).

También asegúrese de que la disposición raíz android:layout_width es match_parent en lugar de wrap_content para asegurarse de que toda la fila es seleccionable.

 12
Author: Lawrr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-14 17:21:37

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 el atributo android:foreground...

 11
Author: NixSam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-14 09:37:14

Desafortunadamente usar vistas enfocables para simular la selección de elementos no es una buena solución porque:

  • El foco se pierde cuando notifyDataSetChanged se llama
  • El enfoque es problemático cuando las vistas secundarias son enfocables

Escribí una clase de adaptador base para manejar automáticamente la selección de elementos con un RecyclerView. Simplemente derive su adaptador de él y use listas de estados de elementos de diseño con state_selected, como haría con una vista de lista.

Tengo una Entrada de Blog Aquí al respecto, 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);
                }
            });
        }
    }
} 
 6
Author: Greg Ennis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-03 18:12:40
    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
Author: jingyuan iu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-04 06:15:04

Agregue este atributo a continuación en su Elemento "my_list_item.xml "
android:descendantFocusability="blocksDescendants" Esto funciona para mí !

 3
Author: Rajiv Manivannan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-17 09:21:12

Debe establecer android:clickable="true" en el elemento xml, y si tiene más selectores en alguna vista dentro de su vista, debe establecer android:duplicateParentState="true" allí también. Eso funciona en apis pre honeycomb.

 1
Author: Bruno Pinto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-20 18:40:07

Como muchos otros respondieron, la única manera es combinar selectores y nuevas Clases para realizar un seguimiento de la selección, pero es mejor delegar este cálculo al Adaptador. La biblioteca FlexibleAdapter realiza un seguimiento de las selecciones por usted, el cambio de configuración también es compatible.

Fondos de color con ondulación ahora se puede hacer sin parte XML, pero en el código para administrar los 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, echa un vistazo a la descripción, las páginas Wiki y el ejemplo completo: https://github.com/davideas/FlexibleAdapter

 0
Author: Davidea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-27 13:17:08

En su diseño o archivo xml simplemente coloque las siguientes líneas.

android:clickable="true"
android:focusable="true"
android:background="?android:attr/activatedBackgroundIndicator"
 0
Author: Juboraj Sarker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-27 07:36:37