2012-07-11 47 views
52

Tengo problemas con listview. sus elementos (filas) tienen botón de imagen. imagebutton tiene "android: onClick", por lo que este evento onclick funciona, pero hacer clic en row doesnt work. si elimino imagebutton del elemento de la fila, hago clic en la fila funciona (listview tiene el onclick listner correcto). Cómo puedo arreglarlo ? Necesito evento onclick cuando el usuario haga clic en ImageButton y evento de clic standart, cuando el usuario seleccione la fila (no haga clic en el ImageButton pero haga clic en la fila)no se puede hacer clic en la fila de vista de lista con imagebutton

mi vista de lista:

<ListView xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/restaurants_list" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:divider="@color/list_devider" 
     android:dividerHeight="1dp" 
     android:cacheColorHint="@color/list_background" /> 

Respuesta

170

Desafortunadamente,

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

no funciona para ImageButton.

Finalmente encontré la solución here. En su diseño xml para esos elementos, agregue

android:descendantFocusability="blocksDescendants" 

a la vista raíz.

Funciona perfectamente para un ListView que tiene ImageButton s. De acuerdo con official reference, blocksDescendants significa que ViewGroup impedirá que sus descendientes reciban el enfoque.

+9

Para 'ToggleButton' el' android: focusable = "false" 'es suficiente, pero para un ImageButton solo' android: descenddantFocusability = "blocksDescendants" 'funcionará. –

+0

¡Agregué este código a la vista de raíz de mi elemento de lista y funciona! Puedo hacer clic en la vista de lista y en el ImageButton sin ningún problema. Gracias –

6

Si una fila de ListView tiene ninguna se puede hacer clic elemento como Button, Image ..etc..then onItemClick no funcionará. Por lo tanto, debe escribir el detector de clics en getView de su adaptador de lista.

Para obtener más información, this.

8

Puede usar un adaptador personalizado para su listaView (si no lo ha hecho). Y allí, en el método del adaptador getView(int position, View inView, ViewGroup parent) hacer algo como esto:

@Override 
public View getView(int position, View inView, ViewGroup parent) { 

    View v = inView; 
    ViewHolder viewHolder; //Use a viewholder for sufficent use of the listview 

    if (v == null) { 
     LayoutInflater inflater = (LayoutInflater) adaptersContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = inflater.inflate(R.layout.list_item, null); 
     viewHolder = new ViewHolder(); 
     viewHolder.image = (ImageView) v.findViewById(R.id.ImageView); 
     v.setTag(viewHolder); 
    } else { 
     viewHolder = (ViewHolder) v.getTag(); 
    } 

     ..... 

    viewHolder.image.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 

      //Click on imageView 
     }i 
    }); 

    v.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 

      //Click on listView row 
     } 
    }); 

     ..... 

    return (v); 
} 

Ver here si necesita ayuda para la creación de su adaptador personalizado.

+0

Tenga en cuenta que esta solución evita que se seleccione la fila. En ciertos casos, es posible que desee una vista de lista donde puede seleccionar una fila Y hacer clic en un botón dentro de una fila. – AndroidDev

+0

¿Es deseable crear un nuevo oyente para cada vista solicitada? – Maarten

+0

@Maarten Si por deseable quiere decir eficiente, entonces es eficiente ya que al usar la técnica 'ViewHolder',' ListView' almacenará en la memoria solamente las filas necesarias y no todas las filas. – Angelo

2

establecer estas propiedades para su botón:

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

O se puede configurar de forma dinámica en su clase de adaptador:

 yourButton.setFocusable(false); 
    yourButton.setFocusableInTouchMode(false); 

Y asegúrese de que se establece el modo de elección como single para la vista de lista :

 listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 
+0

Esto no funciona. ¿Lo has verificado? – z5h

+0

Me funcionó, ¿por qué dices que no funciona? Tengo una fila con una casilla de verificación, otras cosas y el botón. La fila puede ser seleccionada, y el botón y la casilla de verificación también. – David

+0

Sin embargo, es realmente extraño que android: focusable = "false" no funcione para ImageButton. – Eliko

1

Si una fila tiene múltiples elementos seleccionables, onItemClick() no funcionará. Tendrá que configurar el OnClickListener en el método getView(). Almacene a los oyentes la etiqueta de la Vista para que puedan ser reciclados, agregue métodos a sus oyentes para que puedan ser especializados para diferentes filas.

 @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
     View view = super.getView(position, convertView, parent); 

     RowClickListeners listeners = (RowClickListeners) view.getTag(); 
     if (listeners == null) { 
      listeners = new RowClickListeners(); 
     } 

     // Row click listener: 
     RowClickListener onClickListener = listeners.rowClickListener; 
     if (onClickListener == null) { 
      onClickListener = new RowClickListener(); 
      listeners.rowClickListener = onClickListener; 
     } 
        onClickListener.setToPosition(pos); 
     view.setOnClickListener(onClickListener); 

     // Overflow listener: 
     View btn = view.findViewById(R.id.ic_row_btn); 
     ButtonListener btnListener = listeners.buttonClickListener; 
     if (rowListener == null) { 
      btnListener = new ButtonListener(activity); 
      listeners.rowClickListener = btnListener; 
     } 
        btnListener.setToPosition(pos); 
     btnListener.setCollection(collectionId); 
     btn.setOnClickListener(btnListener); 
    } 


    public static class RowClickListeners { 
     public RowClickListener rowClickListener; 
     public ButtonListener buttonClickListener; 
    } 
1

En mi caso, android:descendantFocusability="blocksDescendants" para la capa principal no funcionó, ni en ListView. También probé android:focusable="false" android:focusableInTouchMode="false" que escuché que está funcionando para Buttons, pero tenía ImageButton así que no.

Pero establecer las propiedades del botón en el archivo CS del Diseño funcionó.

var imageButton = view.FindViewById<ImageButton>(Resource.Id.imageButton1); 
imageButton.Focusable = false; 
imageButton.FocusableInTouchMode = false; 
imageButton.Clickable = true; 
+0

Estoy usando mi propio ImageButton. ninguna de las otras respuestas funcionó para mí, pero esto funciona. (Los usé en mi Adaptador personalizado) – Sdghasemi

0

Ninguna de las respuestas anteriores funcionó para mí, pero una combinación sí.

ahora establecer android:descendantFocusability="blocksDescendants" en el ListView y android:focusable="false" android:focusableInTouchMode="false" en los ImageButtons en el XML Y en Java también me puse descendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS) en el ListView y focusable(false), focusableInTouchMode(false), clickable(true) en los ImageButtons.

Cuestiones relacionadas