OnItemCLickListener no funciona en la vista de lista

242

Activity código de clase:

conversationList = (ListView)findViewById(android.R.id.list);
ConversationArrayAdapter conversationArrayAdapter=new  ConversationArrayAdapter(this, R.layout.conversation_list_item_format_left, conversationDetails);
conversationList.setAdapter(conversationArrayAdapter);
conversationList.setOnItemClickListener(new AdapterView.OnItemClickListener(){ 
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
        Log.d("test","clicked");
    }
});

La getViewfunción en la Adapterclase:

if (v == null) {                                
    LayoutInflater vi = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if(leftSideMessageNumber.equals(m.getTo())) {
        v = vi.inflate(R.layout.conversation_list_item_format_left, null);
    } else {
        v = vi.inflate(R.layout.conversation_list_item_format_right, null);
    }
}

¿Hay algún problema con el uso de dos xmls mientras se infla?

hiei
fuente
44
@hiei Mi problema era que estaba usando botones de imagen en mis celdas de diseño. Incluso después de agregar "android: descendantFocusability" mi escucha de clics no respondía. Lo que hice fue cambiar todos los ImaegButtons a ImageViews. Eso resolvió mi problema.
Ajith Memana

Respuestas:

730

Acabo de encontrar una solución desde aquí, pero haciendo clic profundo.

Si algún elemento de la fila de la lista contiene una vista enfocable o seleccionable, entonces OnItemClickListenerno funcionará.

El elemento de la fila debe tener un parámetro similar android:descendantFocusability = "blocksDescendants".

Aquí puede ver un ejemplo de cómo debería verse su elemento de la lista. Su elemento de lista xml debe ser ... row_item.xml( your_xml_file.xml)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:baselineAligned="false"
    android:descendantFocusability="blocksDescendants"
    android:gravity="center_vertical" >

    // your other widgets here

</LinearLayout>
Bhavesh Hirpara
fuente
no funciona para mi ¿Alguien puede echar un vistazo a [ stackoverflow.com/questions/21692209/…
suitianshi
3
También puede establecer mediante programación con este listView.setDescendantFocusability(int focus);, donde focuses uno de ViewGroup.FOCUS_BEFORE_DESCENDANTS, ViewGroup.FOCUS_AFTER_DESCENDANTSoViewGroup.FOCUS_BLOCK_DESCENDANTS
Max huargo
Creo que es divertido que 20 personas te hayan agradecido en un comentario. Me he encontrado con este problema durante las últimas 8 horas, muchas gracias por esto.
sparticvs
1
Mi pregunta es si se trata de un error de Android o es por diseño.
fangzhzh
He estado atrapado en esto durante 6 horas y realmente necesito ayuda. stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/…
Ruchir Baronia
89

El problema es que sus diseños contienen elementos enfocables o seleccionables. Si una vista contiene elementos enfocables o seleccionables, no se llamará a OnItemCLickListener.

Haga clic aquí para más información.

Publique uno de sus xmls de diseño si ese no es el caso.

balazsbalazs
fuente
2
Esta fue la solución para mí, estaba declarando mi vista como clicable. ¡Gracias!
Kingraam
1
¡Gracias! Cambié mis 2 EditTextsa TextViews, y CheckBoxse me permitió permanecer (y permanecer activable) con android:descendantFocusability="blocksDescendants"agregado a mi LinearLayout.
Azurespot
¡Si! Tenía android:focusableInTouchMode="true"para la fila, una vez eliminada comenzó a funcionar por fin! :-)
SharpC
58

Para mis listas, mis filas tienen otras cosas en las que se puede hacer clic, como botones, por lo que hacer una manta blocksDescendantsno funciona. En cambio, agregué una línea en el botón xml:

android:focusable="false"

Eso evita que los botones bloqueen los clics en las filas, pero aún permite que los botones tomen los clics.

Janene Pappas
fuente
@ user1840899 Esta es una respuesta común y una de la que aprendí, así que la transmití. Es información correcta, no digna de voto negativo.
Janene Pappas
Esto funciona para mí en un CheckBox en elementos ListView (sin bloques Descendientes)
thpitsch
Esto corrige el error al tiempo que se puede hacer clic en los botones (ToggleButton para mí)
Mohsen Afshin
La única forma en que pude obtener un GridView con RadioButtons funcionando fue aplicando android: descendantFocusability = "blocksDescendants" en LinearLayout que contiene RadioButton, y configurando android: clickable = "false" en RadioButton.
Stephen McCormick
He estado atrapado en esto durante 6 horas y realmente necesito ayuda. stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/…
Ruchir Baronia
34

necesitas hacer 2 pasos en tu listview_item.xml

  1. establecer el diseño raíz con: android:descendantFocusability="blocksDescendants"
  2. configure cualquier vista enfocable o cliqueable en este elemento con:
    android:clickable="false"
    android:focusable="false"
    android:focusableInTouchMode="false"

Aquí hay un ejemplo: listview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="10dp"
    android:layout_marginTop="10dp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:gravity="center_vertical"
    android:orientation="vertical"
    android:descendantFocusability="blocksDescendants">

    <RadioButton
        android:id="@+id/script_name_radio_btn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:textColor="#000"
        android:padding="5dp"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        />

</LinearLayout>
Remolino
fuente
La configuración clickable="trueen la vista del elemento hará que onItemClickno se llame. Así que preste atención para agregar también clickable="false"en la vista raíz del elemento, en este caso es elLinearLayout
vovahost
Configurar android: descendantFocusability = "blocksDescendants" me ayuda. ¡Gracias!
LLIAJLbHOu
21/12/16, y después de horas de búsqueda, esto funcionó, ¡gracias hombre!
Tanner Summers
Si tiene el mismo diseño que el paisaje, etc., asegúrese de hacerlo también allí.
Immy
19

use el código a continuación dentro de la etiqueta del botón en el diseño de fila personalizado de la vista de lista

 android:focusable="false"
 android:clickable="false"
Milan Shukla
fuente
Great Man fue realmente servicial !!
divyansh ingle
esto funcionó aquí !! Tengo muchas casillas de verificación en esta vista y trato de android:descendantFocusability="blocksDescendants"bloquear estas casillas de verificación para hacer clic
Armando Marques Sobrinho
17

Tuve el mismo problema y acabo de ver que accidentalmente había configurado:

@Override
public boolean isEnabled(int position)
{
    return false;
}

en mi clase CustomListViewAdapter.

Al cambiar esto a:

return true;

Me las arreglé para solucionar el problema. Por si acaso si alguien ha cometido el mismo error ...

Leñoso
fuente
77
Yo también tuve un@Override public void onApplicationStart { ExplodeThisDevice(); }
Léon Pelletier
17

Use android: descenddantFocusability

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="80dip"
    android:background="@color/light_green"
    android:descendantFocusability="blocksDescendants" >

Agregar arriba en el diseño raíz

Amar Gore
fuente
2
Agregar detalles podría hacer que esta sea una mejor respuesta y +1.
Asesino
Esto funcionó para mí y mi botón en el elemento de la lista todavía funcionó según lo previsto.
Gustav Eriksson
11

Lo resolví con la ayuda de esta respuesta

1.Agregue lo siguiente en Diseño lineal de list_items.xml android:descendantFocusability="blocksDescendants"

2. Vistas infantiles de LinearLayout en list_items.xml

 android:focusable="false" 
RAJESH KUMAR ARUMUGAM
fuente
Tu enlace está roto.
Jason C
1
@ JasonC Gracias por su información. Aquí está el enlace stackoverflow.com/a/14915758/5740760
RAJESH KUMAR ARUMUGAM
10

si tiene vistas de texto, botones o stg clicables o seleccionables solo en su vista de fila

android:descendantFocusability="blocksDescendants"

no es suficiente. Tienes que configurar

android:textIsSelectable="false"

a sus vistas de texto y

android:focusable="false"

a sus botones y otros elementos enfocables.

población
fuente
Aprendí esto de la manera difícil. android: textIsSelectable = "false" Vigila esto :)
diyoda_
10

Incluso estaba teniendo el mismo problema, tengo una casilla de verificación, hice lo siguiente para enmascarar el elemento itemClickListener,

Se agregaron las siguientes propiedades a la casilla de verificación,

android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"

y ItemClickListner comenzó a funcionar.

Para un ejemplo detallado, puede ir a través del enlace,

http://knowledge-cess.com/android-itemclicklistner-with-checkbox-or-radiobutton/

Espero que ayude ¡Salud!

Gokul Kulkarni
fuente
5

Tuve el mismo problema y probé todas las soluciones mencionadas en vano. a través de las pruebas descubrí que hacer que el texto fuera seleccionable impedía que se llamara al oyente. Entonces, al cambiarlo a falso o al eliminarlo, se volvió a llamar a mi oyente.

android:textIsSelectable="false"

Espero que esto ayude a alguien que estaba atrapado como yo.

u2tall
fuente
4
  1. Agregue esto en el diseño principal

    android:descendantFocusability="blocksDescendants"
  2. Escriba este código en cada botón, Textview, ImageView, etc. que tienen onClick

    android:focusable="false"
    
    android:clickable="false"

Espero que funcione.

Wajid khan
fuente
3

Dos soluciones asombrosas fueron esto: si extiende ListFragment desde un fragmento, sepa que mListView.setOnItemClickListenerno se llamará antes de que se cree su actividad, esto garantiza que se establezca cuando se haya creado la actividad

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    mListView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int position, long rowId) {
            // Do the onItemClick action

            Log.d("ROWSELECT", "" + rowId);
        }
    });
}

Mientras miraba el código fuente de ListFragment, me encontré con esto

public class ListFragment extends Fragment {
    ...........................................
    ................................................

    final private AdapterView.OnItemClickListener mOnClickListener
                = new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            onListItemClick((ListView)parent, v, position, id);
        }
    };

    ................................................................
    ................................................................

    public void onListItemClick(ListView l, View v, int position, long id) {
    }
}

Se onItemClickListeneradjunta un objeto y llama onListItemClick() Como tal, la otra solución similar, que funciona exactamente de la misma manera, es anularonListItemClick()

@Override
public void onListItemClick(ListView l, View v, int position, long rowId) {
    super.onListItemClick(l, v, position, id);
   // Do the onItemClick action

   Log.d("ROWSELECT", "" + rowId);
} 
Rowland Mtetezi
fuente
3

en mi caso, ninguna de las propiedades de diseño xml no fue útil.

Solo agrego una sola línea de código como esta: convertView.setClickable (false);

@NonNull
@Override
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
    ViewHolder viewHolder;
    if (convertView == null || convertView.getTag() == null) {
        LayoutInflater inflater = LayoutInflater.from(context);
        convertView = inflater.inflate(R.layout.my_layout_id, parent, false);
        viewHolder = new ViewHolder(convertView);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    ...
    convertView.setClickable(false);
    return convertView;
}

Básicamente, hace lo mismo que configurar las propiedades en el diseño xml, pero fue lo único que funcionó en mi caso.

No es el momento perfecto, pero tal vez ayude a alguien Codificación feliz

Marek Skóra
fuente
1

He intentado todo lo anterior y NADA funcionó.

Resolví el problema de la siguiente manera:

Primero defino un botón personalizado llamado ListButton

public class ListButton extends android.widget.Button
{

private ButtonClickedListener clickListener;

public ListButton(Context context)
{
    this(context, null);
}

public ListButton(Context context, AttributeSet attrs)
{
    this(context, attrs, 0);
}

public ListButton(Context context, AttributeSet attrs, int defStyle)
{
    super(context, attrs, defStyle);
}

public void setClickListener(ButtonClickedListener listener) {
    this.clickListener = listener;
}

@Override
public boolean isInTouchMode() {
    return true;
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    return false;
}

@Override
public boolean dispatchTouchEvent(MotionEvent event) {

    switch (event.getAction()) 
      {
          case MotionEvent.ACTION_DOWN:
              break;
          case MotionEvent.ACTION_UP:

              eventClicked();

              break;
          case MotionEvent.ACTION_CANCEL:
              break;
          case MotionEvent.ACTION_MOVE:
              break;
          default :

      }
    return true;
}

private void eventClicked() {
    if (this.clickListener!=null) {
        this.clickListener.ButtonClicked();
    }
}

}

El XML se ve así:

<dk.example.views.ListButton
android:id="@+id/cancel_button"
android:layout_width="125dp"
android:layout_height="80dp"
android:text="Cancel"
android:textSize="20sp" 
android:layout_margin="10dp"
android:padding="2dp"
android:background="#000000"
android:textColor="#ffffff"
android:textStyle="bold"  
/>

Luego defino mi propia ButtonClickedinterfaz de escucha:

public interface ButtonClickedListener {
    public void ButtonClicked();
}

Luego uso mi propio oyente como si fuera lo normal OnClickListener:

final ListButton cancelButton = (ListButton) viewLayout.findViewById(R.id.cancel_button);

    cancelButton.setClickListener(new ButtonClickedListener() {

        @Override
        public void ButtonClicked() {
            //Do your own stuff here...
        }

    });
AndreasReiff
fuente
1

Tuve el mismo problema, estaba usando un estilo para mis textos en el diseño de fila que tenía el atributo "enfocable". Funcionó después de que lo quité.

Miguel Rdz
fuente
1

En mi caso, tuve que eliminar la siguiente línea del Layout

android:clickable="true"
IgniteCoders
fuente
1

Android: el atributo autoText también hace que TextView sea auto enfocable.

Yury Finchenko
fuente
0

Si desea utilizar tanto el clic simple como el clic largo en los elementos de vista de lista, una mejor manera de implementarlo sería usar el menú contextual para hacer clic largo. Evite usar setItemLongClickListener, especialmente si tiene múltiples diseños de fila para su vista de lista.

Samuel Robert
fuente
0

Enfrenté el mismo problema, lo intenté durante horas. Si ha intentado todo lo anterior, intente cambiar layout_width de Listview y list item a match_parent de wrap_content.

prashant
fuente
0

Todo lo anterior falló para mí. Sin embargo, pude resolver el problema (después de muchas horas de golpearme la cabeza: Google, si está escuchando, considere corregir lo que encontré a continuación en forma de errores del compilador, si es posible)

Realmente debe tener cuidado con los atributos de Android que agrega a su diseño xml aquí (en esta pregunta original, se llama list_items.xml). Para mí, lo que estaba causando el problema era que había cambiado de una vista EditText a TextView y me quedaba el atributo sobrante del cambio (en mi caso, inputType). El compilador no lo captó y la capacidad de hacer clic simplemente falló cuando fui a ejecutar la aplicación. Verifique todos los atributos que tiene en sus nodos xml de diseño.

Ted_Zactly
fuente
0
private AdapterView.OnItemClickListener onItemClickListener;

@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
 .......

final View view = convertView;
convertView.setOnClickListener(new View.OnClickListener() {
    @Override
     public void onClick(View v) {
         if (onItemClickListener != null) {
             onItemClickListener.onItemClick(null, view, position, -1);
         }
      }
 });

return convertView;
}

public void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {
    this.onItemClickListener = onItemClickListener;
}

Luego, en su actividad, use adapter.setOnItemClickListener () antes de adjuntarlo a la vista de lista.

Copiado de github me funcionó

Muhammad Waleed
fuente
0

Lo que funcionó para mí fue agregar el siguiente código a cada subvista dentro del diseño de mi archivo row.xml:

android:focusable="false"
android:focusableInTouchMode="false"

Entonces en mi caso:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/testingId"
        android:text="Name"
       //other stuff 
        />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/dummyId"
        android:text="icon"
        //other stuff 
        />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/assignmentColor"
       //other stuff 
       />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/testID"
        //other stuff 
        />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:text="TextView"
        //other stuff 
        />

</android.support.constraint.ConstraintLayout>

Y esta es mi llamada a setOnItemClickListener en mi subclase Fragment:

CustomListView = (PullToRefreshListCustomView) layout.findViewById(getListResourceID());
        CustomListView.setAdapter(customAdapter);
        CustomListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.d("Testing", "onitem click working");
              //  other code
            }

        });

¡Tengo la respuesta de aquí !

spcarlin
fuente
-1

Resolví el problema eliminando las vistas cliqueables de la lista.

sidKhalid
fuente