Android: elementos ListView con múltiples botones en los que se puede hacer clic

Resuelto znq asked hace 54 años • 8 respuestas

Tengo un ListViewlugar donde cada elemento de la lista contiene un TextView y dos botones diferentes. Algo como esto:

ListView
--------------------
[Text]
[Button 1][Button 2]
--------------------
[Text]
[Button 1][Button 2]
--------------------
... (and so on) ...

Con este código puedo crear un OnItemClickListenerpara todo el artículo:

listView.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> list, View view, int position, long id) {
        Log.i(TAG, "onListItemClick: " + position);

        }

    }
});

Sin embargo, no quiero que se pueda hacer clic en todo el elemento, sino solo en los dos botones de cada elemento de la lista.

Entonces mi pregunta es, ¿cómo implemento un onClickListener para estos dos botones con los siguientes parámetros?

  • int button(en qué botón del elemento se ha hecho clic)
  • int position(que es el elemento de la lista en el que se hizo clic en el botón)

Actualización: encontré una solución como se describe en mi respuesta a continuación. Ahora puedo hacer clic/tocar el botón a través de la pantalla táctil. Sin embargo, no puedo seleccionarlo manualmente con la bola de seguimiento. Siempre selecciona todo el elemento de la lista y desde allí va directamente al siguiente elemento de la lista ignorando los botones, aunque configuré .setFocusable(true)y setClickable(true)para los botones en getView().

También agregué este código a mi adaptador de lista personalizado:

@Override
public boolean  areAllItemsEnabled() {
    return false;           
}

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

Esto hace que ya no se pueda seleccionar ningún elemento de la lista. Pero no ayudó a que los botones anidados fueran seleccionables.

¿Alguien tiene una idea?

znq avatar Jan 01 '70 08:01 znq
Aceptado

La solución a esto es en realidad más fácil de lo que pensaba. Simplemente puede agregar en getView()el método de su adaptador personalizado un setOnClickListener() para los botones que está utilizando.

Cualquier dato asociado con el botón debe agregarse en myButton.setTag()y getView()se puede acceder a él en onClickListener a través deview.getTag()

Publiqué una solución detallada en mi blog como tutorial.

znq avatar Nov 21 '2009 18:11 znq

Esta es una especie de apéndice de la respuesta de @znq...

Hay muchos casos en los que desea saber la posición de la fila de un elemento en el que se hizo clic Y desea saber qué vista de la fila se presionó. Esto será mucho más importante en las interfaces de usuario de tabletas.

Puede hacer esto con el siguiente adaptador personalizado:

private static class CustomCursorAdapter extends CursorAdapter {

    protected ListView mListView;

    protected static class RowViewHolder {
        public TextView mTitle;
        public TextView mText;
    }

    public CustomCursorAdapter(Activity activity) {
        super();
        mListView = activity.getListView();
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        // do what you need to do
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View view = View.inflate(context, R.layout.row_layout, null);

        RowViewHolder holder = new RowViewHolder();
        holder.mTitle = (TextView) view.findViewById(R.id.Title);
        holder.mText = (TextView) view.findViewById(R.id.Text);

        holder.mTitle.setOnClickListener(mOnTitleClickListener);
        holder.mText.setOnClickListener(mOnTextClickListener);

        view.setTag(holder);

        return view;
    }

    private OnClickListener mOnTitleClickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            final int position = mListView.getPositionForView((View) v.getParent());
            Log.v(TAG, "Title clicked, row %d", position);
        }
    };

    private OnClickListener mOnTextClickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            final int position = mListView.getPositionForView((View) v.getParent());
            Log.v(TAG, "Text clicked, row %d", position);
        }
    };
}
greg7gkb avatar Mar 16 '2011 02:03 greg7gkb

Para futuros lectores:

Para seleccionar manualmente los botones con el trackball utilice:

myListView.setItemsCanFocus(true);

Y para desactivar el enfoque en todos los elementos de la lista:

myListView.setFocusable(false);
myListView.setFocusableInTouchMode(false);
myListView.setClickable(false);

A mí me funciona bien, puedo hacer clic en los botones con la pantalla táctil y también me permite enfocar un clic usando el teclado.

Rudolf Real avatar Mar 23 '2012 14:03 Rudolf Real

No tengo mucha experiencia que los usuarios anteriores, pero enfrenté el mismo problema y lo resolví con la siguiente solución.

<Button
        android:id="@+id/btnRemove"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/btnEdit"
        android:layout_weight="1"
        android:background="@drawable/btn"
        android:text="@string/remove" 
        android:onClick="btnRemoveClick"
        />

btnRemoveClick Evento de clic

public void btnRemoveClick(View v)
{
    final int position = listviewItem.getPositionForView((View) v.getParent()); 
    listItem.remove(position);
    ItemAdapter.notifyDataSetChanged();

}
Bhavin Chauhan avatar Jun 22 '2013 05:06 Bhavin Chauhan

Probablemente hayas encontrado cómo hacerlo, pero puedes llamar

ListView.setItemsCanFocus(true)

y ahora tus botones captarán el foco

Rafal avatar Aug 02 '2010 20:08 Rafal