Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Android: elementos ListView con varios botones que se pueden hacer clic

Tengo un ListView donde cada elemento en 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 OnItemClickListener para 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 todo el elemento sea clicable, sino sólo los dos botones de cada elemento de lista.

Así que mi pregunta es, ¿cómo implemento un onClickListener para estos dos botones con los siguientes parámetros:

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

Actualización: he encontrado 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 rueda de desplazamiento. Siempre selecciona todo el elemento de la lista y desde allí va directamente al siguiente elemento de lista ignorando los botones, aunque establezco .setFocusable(true) y setClickable(true) para los botones de getView() .

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

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

Esto hace que ningún elemento de la lista sea seleccionable en absoluto. Pero no ayudó en la selección de los botones anidados.

Alguien una idea?

  • ListView y los botones dentro de ListView
  • Elemento de lista con el botón que ya no se puede hacer clic
  • Pasar un parámetro al oyente onclick en un botón de una fila listview
  • 8 Solutions collect form web for “Android: elementos ListView con varios botones que se pueden hacer clic”

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

    Cualquier dato asociado con el botón tiene que ser agregado con myButton.setTag() en el getView() y se puede acceder en el onClickListener vía view.getTag()

    He publicado una solución detallada en mi blog como un tutorial.

    Esto es una especie de apéndice respuesta de @ znq …

    Hay muchos casos en los que desea conocer la posición de fila de un elemento que se ha hecho clic y desea saber qué vista de la fila se ha activado. Esto va a ser mucho más importante en Tablet UIs.

    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); } }; } 

    Para futuros lectores:

    Para seleccionar manualmente los botones con la esfera de desplazamiento utilice:

     myListView.setItemsCanFocus(true); 

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

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

    Funciona bien para mí, puedo hacer clic en los botones con pantalla táctil y también alows enfocar un clic con el teclado

    No tengo mucha experiencia que encima de usuarios pero he hecho frente a este mismo problema y he resuelto esto con abajo 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 Haga clic en evento

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

    Probablemente has encontrado cómo hacerlo, pero puedes llamar

     ListView.setItemsCanFocus(true) 

    Y ahora sus botones se centrará

    No estoy seguro de ser la mejor manera, pero funciona bien y todo el código permanece en su ArrayAdapter.

     package br.com.fontolan.pessoas.arrayadapter; import java.util.List; import android.content.Context; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.ImageView; import br.com.fontolan.pessoas.R; import br.com.fontolan.pessoas.model.Telefone; public class TelefoneArrayAdapter extends ArrayAdapter<Telefone> { private TelefoneArrayAdapter telefoneArrayAdapter = null; private Context context; private EditText tipoEditText = null; private EditText telefoneEditText = null; private ImageView deleteImageView = null; public TelefoneArrayAdapter(Context context, List<Telefone> values) { super(context, R.layout.telefone_form, values); this.telefoneArrayAdapter = this; this.context = context; } @Override public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.telefone_form, parent, false); tipoEditText = (EditText) view.findViewById(R.id.telefone_form_tipo); telefoneEditText = (EditText) view.findViewById(R.id.telefone_form_telefone); deleteImageView = (ImageView) view.findViewById(R.id.telefone_form_delete_image); final int i = position; final Telefone telefone = this.getItem(position); tipoEditText.setText(telefone.getTipo()); telefoneEditText.setText(telefone.getTelefone()); TextWatcher tipoTextWatcher = new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { telefoneArrayAdapter.getItem(i).setTipo(s.toString()); telefoneArrayAdapter.getItem(i).setIsDirty(true); } }; TextWatcher telefoneTextWatcher = new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { telefoneArrayAdapter.getItem(i).setTelefone(s.toString()); telefoneArrayAdapter.getItem(i).setIsDirty(true); } }; tipoEditText.addTextChangedListener(tipoTextWatcher); telefoneEditText.addTextChangedListener(telefoneTextWatcher); deleteImageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { telefoneArrayAdapter.remove(telefone); } }); return view; } } 

    Sé que es tarde, pero esto puede ayudar, este es un ejemplo de cómo escribir clase de adaptador personalizado para diferentes acciones de clic

      public class CustomAdapter extends BaseAdapter { TextView title; Button button1,button2; public long getItemId(int position) { return position; } public int getCount() { return mAlBasicItemsnav.size(); // size of your list array } public Object getItem(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = getLayoutInflater().inflate(R.layout.listnavsub_layout, null, false); // use sublayout which you want to inflate in your each list item } title = (TextView) convertView.findViewById(R.id.textViewnav); // see you have to find id by using convertView.findViewById title.setText(mAlBasicItemsnav.get(position)); button1=(Button) convertView.findViewById(R.id.button1); button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //your click action // if you have different click action at different positions then if(position==0) { //click action of 1st list item on button click } if(position==1) { //click action of 2st list item on button click } }); // similarly for button 2 button2=(Button) convertView.findViewById(R.id.button2); button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //your click action }); return convertView; } } 

    ¿No es la solución de plataforma para esta implementación utilizar un menú contextual que se muestra en una prensa larga?

    ¿Está el autor de la pregunta consciente de los menús contextuales? Apilar botones en un listview tiene implicaciones de rendimiento, desordenará su interfaz de usuario y violará el diseño de interfaz de usuario recomendado para la plataforma.

    En el flipside; Los menús contextuales -por naturaleza de no tener una representación pasiva- no son evidentes para el usuario final. Considere documentar el comportamiento?

    Esta guía debe darle un buen comienzo.

    http://www.mikeplate.com/2010/01/21/show-a-context-menu-for-long-clicks-in-an-android-listview/

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.