¿Cómo agrego un onclicklistener a un botón dentro de un adaptador listview?

Tengo un listview que contiene la lista de todos mis usuarios. Cada elemento de la lista es un diseño que tiene un botón para mostrar un AlertDialog para cambiar el valor de la etiqueta del botón. ¿Cómo puedo agregar dinámicamente un evento de clic a ese botón que es generado por el adaptador listview?

Este es mi adaptador:

public class PerfilAdapter extends BaseAdapter { Context mContext; LayoutInflater mLayoutInflater; List<PerfilBean> listaPerfiles = new ArrayList<PerfilBean>(); public Settings01 set=new Settings01(); public PerfilAdapter(Context context,List<PerfilBean> lista) { mContext = context; mLayoutInflater = (LayoutInflater) mContext .getSystemService(Context.LAYOUT_INFLATER_SERVICE); listaPerfiles=lista; } @Override public int getCount() { // TODO Auto-generated method stub return listaPerfiles.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return listaPerfiles.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { RelativeLayout itemView; if (convertView == null) { itemView = (RelativeLayout) mLayoutInflater.inflate( R.layout.item_perfil, parent, false); } else { itemView = (RelativeLayout) convertView; } // obtengo los valores de la vista Button moneda = (Button) itemView.findViewById(R.id.Moneda); TextView titulo = (TextView) itemView.findViewById(R.id.Titulo); TextView nombredesc = (TextView) itemView.findViewById(R.id.txtNombre); TextView descripcion = (TextView) itemView.findViewById(R.id.txtDescripcion); String nombreM = Metodos.monedas[listaPerfiles.get(position).getPerfil_tipoMoneda()]; moneda.setText(nombreM); titulo.setText(listaPerfiles.get(position).getPerfil_nombre()); nombredesc.setText(listaPerfiles.get(position).getPerfil_nombreSec()); descripcion.setText(listaPerfiles.get(position).getPerfil_texto()); return itemView; } // metodo parahacer la vista de la celda public void actualizaDatosLista(List<PerfilBean> listaPerfilesM) { for(int i=0;i<listaPerfilesM.size();i++){ Log.d("ITEM "+i,listaPerfilesM.get(i).getPerfil_nombreSec()); } listaPerfiles = listaPerfilesM; notifyDataSetChanged(); }} 

Y esta es mi Actividad:

 public class Settings01 extends Activity implements OnClickListener { private List<PerfilBean> lst; private PerfilDAO perfildao; private PerfilAdapter perfiladapter; private ListView lstPerfiles; public void changeMoneda(final int position) { int x = 0; AlertDialog.Builder builder = new AlertDialog.Builder(Settings01.this); builder.setTitle("Seleccione Tipo de Distribuidor"); builder.setItems(R.array.moneda, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { lst.get(position).setPerfil_tipoMoneda(item); perfiladapter = new PerfilAdapter(getApplicationContext(), lst); lstPerfiles.setAdapter(perfiladapter); dialog.dismiss(); } }); builder.create(); builder.show(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.settings01); lstPerfiles = (ListView) findViewById(R.id.lstSettings); perfildao = new PerfilDAOImplDB(Settings01.this); lst = new ArrayList<PerfilBean>(); lst = perfildao.getAll(); perfiladapter = new PerfilAdapter(getApplicationContext(), lst); Log.d("Info", "En Settings"); lstPerfiles.setAdapter(perfiladapter); } @Override public void onClick(View v) { Log.d("Info", "derp" + v.getId()); }} 

Este es el diseño que mi adaptador utiliza actualmente:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/Titulo" android:layout_width="wrap_content" android:layout_height="40dp" android:layout_alignParentLeft="true" android:layout_marginLeft="150dp" android:gravity="left|center_vertical" android:textColor="@color/Negro" android:text="derp" /> <TextView android:id="@+id/lblTipoMoneda" android:layout_width="120dp" android:layout_height="40dp" android:layout_toLeftOf="@+id/Moneda" android:gravity="left|center_vertical" android:text="Tipo de moneda: " /> <Button android:id="@+id/Moneda" android:layout_width="160dp" android:layout_height="40dp" android:layout_alignParentRight="true" android:layout_marginRight="150dp" android:gravity="left|center_vertical" android:background="@color/Blanco" android:textColor="@color/Negro" android:text="Peso argentino" /> <ImageView android:id="@+id/Separador" android:layout_width="match_parent" android:layout_height="2.5dp" android:layout_below="@+id/Moneda" android:layout_marginLeft="150dp" android:layout_marginRight="150dp" android:background="@color/Negro" /> <TextView android:id="@+id/Nombre" android:layout_width="wrap_content" android:layout_height="40dp" android:layout_alignParentLeft="true" android:layout_below="@+id/Separador" android:layout_marginLeft="150dp" android:layout_marginTop="10dp" android:clickable="true" android:gravity="left|center_vertical" android:onClick="changeMoneda" android:text="Nombre :" /> <EditText android:id="@+id/txtNombre" android:layout_width="200dp" android:layout_height="40dp" android:layout_below="@+id/Separador" android:layout_marginTop="10dp" android:layout_toRightOf="@+id/Nombre" android:background="@drawable/fondotxt" android:textColor="@color/Negro" android:inputType="text" /> <TextView android:id="@+id/lblTitulo" android:layout_width="360dp" android:layout_height="24dp" android:layout_below="@+id/txtNombre" android:layout_marginTop="10dp" /> <EditText android:id="@+id/txtDescripcion" android:layout_width="match_parent" android:layout_height="200dp" android:layout_below="@+id/lblTitulo" android:layout_marginLeft="150dp" android:layout_marginRight="150dp" android:textColor="@color/Negro" android:gravity="left|center_vertical" /> <ImageView android:id="@+id/imgPicturefantes" android:layout_width="100dp" android:layout_height="150dp" android:layout_below="@+id/txtDescripcion" android:layout_toLeftOf="@+id/lblFotoAntes" android:src="@drawable/what" /> <ImageView android:id="@+id/imgPicturefdespues" android:layout_width="100dp" android:layout_height="150dp" android:layout_below="@+id/txtDescripcion" android:layout_marginLeft="50dp" android:layout_toRightOf="@+id/centerPoint" android:src="@drawable/what" /> <TextView android:id="@+id/lblFotoDespues" android:layout_width="120dp" android:layout_height="50dp" android:layout_below="@+id/txtDescripcion" android:layout_marginTop="50dp" android:layout_toRightOf="@+id/imgPicturefdespues" android:gravity="center" android:text="Foto despues: " android:textSize="18sp" /> <ImageButton android:id="@+id/btnDespuesF" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/btnAntesF" android:layout_toRightOf="@+id/imgPicturefdespues" android:background="@drawable/btnupload" /> <TextView android:id="@+id/centerPoint" android:layout_width="2dp" android:layout_height="2dp" android:layout_below="@+id/txtDescripcion" android:layout_centerHorizontal="true" /> <TextView android:id="@+id/lblFotoAntes" android:layout_width="100dp" android:layout_height="50dp" android:layout_below="@+id/txtDescripcion" android:layout_marginRight="50dp" android:layout_marginTop="50dp" android:layout_toLeftOf="@+id/centerPoint" android:gravity="center" android:text="Foto antes: " android:textSize="18sp" /> <ImageButton android:id="@+id/btnAntesF" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/lblFotoAntes" android:layout_marginRight="75dp" android:layout_toLeftOf="@+id/centerPoint" android:background="@drawable/btnupload" /> 

Puede hacerlo en el método getView() de su adaptador. Para eso necesitarás usar un adaptador personalizado (si no lo estás haciendo ya). Será mejor si puede mostrar las partes pertinentes de su código.

EDIT: El diálogo se mostrará por su actividad. Por lo tanto, puede crear una interfaz para escuchar este evento de clic de botón.

 public interface BtnClickListener { public abstract void onBtnClick(int position); } 

Deje que su adaptador personalizado lo reciba como entrada.

 private BtnClickListener mClickListener = null; public PerfilAdapter(Context context, List<PerfilBean> lista, BtnClickListener listener) { mContext = context; mLayoutInflater = (LayoutInflater) mContext .getSystemService(Context.LAYOUT_INFLATER_SERVICE); listaPerfiles=lista; mClickListener = listener; } 

Ahora puede simplemente establecer el onClickListener normal en getView() como se muestra a continuación

 Button moneda = (Button) itemView.findViewById(R.id.Moneda); moneda.setTag(position); //For passing the list item index moneda.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if(mClickListener != null) mClickListener.onBtnClick((Integer) v.getTag()); } }); 

Deje que su actividad pase el BtnClickListener necesario como parte de la creación del adaptador.

 perfiladapter = new PerfilAdapter(getApplicationContext(), lst, new BtnClickListener() { @Override public void onBtnClick(int position) { // TODO Auto-generated method stub // Call your function which creates and shows the dialog here changeMoneda(position); } }); 

Suponiendo que lst.get(position).setPerfil_tipoMoneda(item); Cambia el texto que se utilizará como botón de texto correctamente, simplemente debe llamar a perfiladapter.notifyDataSetChanged() en el onClick de su dialog (Actualmente está creando el adaptador de nuevo que no es necesario).

 public void onClick(DialogInterface dialog, int item) { lst.get(position).setPerfil_tipoMoneda(item); perfiladapter.notifyDataSetChanged(); dialog.dismiss(); } 

Espero que funcione como usted espera.

En mi caso tuve que añadir este atributo en el listView:

 <ListView ... android:clickable="true" ... </ListView> 

Y en el adaptador simplemente añada el oyente de clics en la vista del botón.

 wrapper.getButtonHi().setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub DebugUtils.logDebug("Clickeado :: "+ mContact.getUserId()); } }); 

Es importante establecer las variables finales:

 public View getRowView(final int position, View convertView, ViewGroup parent) { final BrowseContactItemWrapper wrapper; final UserModel mContact = lstContact.get(position); ..... } 

Sólo un pequeño tweak para actualizar el renderizador desde fuera.

 final FinalMenuListAdapter adapter = this; viewHolder.deleteItem.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(mClickListener != null) mClickListener.onBtnClick((MenuItemObject)v.getTag(),adapter); } }); final MenuItemObject menuItemObject = getItem(position); viewHolder.deleteItem.setTag(menuItemObject); 
  • Cómo controlar ListView con el patrón MVP para Android
  • Anulación de Android ArrayAdapter
  • Cambiar el color del fondo del elemento de lista activado en Honeycomb
  • Android: Cambiar el fondo del botón en ListView Row con onClick
  • Cómo quitar el divisor inferior del pie de página en una vista de lista de android
  • ListView getChildAt devolver null para los niños visibles
  • Android: consigue el i-ésimo TextView dentro de un ListView
  • Android - deshabilitar el elemento de vista de lista haga clic y vuelva a habilitarlo
  • Mostrar toda la música en la tarjeta SD
  • Cómo poner editable editable dentro de un listview?
  • ¿Cuál usar WebView o TextView en una lista con datos HTML en ella?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.