Android 如何将 OnClickListener 添加到 ListView 适配器内的按钮?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20132359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I add an OnClickListener to a button inside a ListView adapter?
提问by user2981113
I have a listview that contains the list of all my users. Every item from the list is a layout that has a button to show an AlertDialog to change the value of the label of the button. How can I dynamically add an on click event to that button that is generated by the listview Adapter?
我有一个包含所有用户列表的列表视图。列表中的每一项都是一个布局,它有一个按钮来显示 AlertDialog 以更改按钮标签的值。如何向由列表视图适配器生成的按钮动态添加点击事件?
This is my adapter:
这是我的适配器:
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();
}}
and this is my Activity:
这是我的活动:
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());
}}
This is the layout that my adapter is currently using:
这是我的适配器当前使用的布局:
<?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" />
回答by Rajeev
You can do so in the getView()
method of your adapter. For that you will need to use a custom adapter (if you are not doing that already). It will be better if you can show the relevant portions of your code.
您可以在getView()
适配器的方法中执行此操作。为此,您将需要使用自定义适配器(如果您还没有这样做)。如果您可以显示代码的相关部分会更好。
EDIT:The dialog will be shown by your activity. So you can create an interface for listening to this button click event.
编辑:您的活动将显示该对话框。所以你可以创建一个接口来监听这个按钮点击事件。
public interface BtnClickListener {
public abstract void onBtnClick(int position);
}
Let your custom adapter receive it as input.
让您的自定义适配器将其作为输入接收。
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;
}
Now you can simply set the normal onClickListener
in getView()
as below
现在,你可以简单的设置正常onClickListener
的getView()
,如下
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());
}
});
Let your activity pass the required BtnClickListener as part of adapter creation.
让您的 Activity 作为适配器创建的一部分传递所需的 BtnClickListener。
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);
}
});
Assuming that lst.get(position).setPerfil_tipoMoneda(item);
changes the text which will be used as button text correctly, you should simply call perfiladapter.notifyDataSetChanged()
in the onClick
of your dialog
(Currently you are creating the adapter again which is not required).
假设lst.get(position).setPerfil_tipoMoneda(item);
的变化将被正确地作为按钮文本的文本,你应该简单地调用perfiladapter.notifyDataSetChanged()
在onClick
你的dialog
(目前正在创建的适配器再次不要求)。
public void onClick(DialogInterface dialog, int item) {
lst.get(position).setPerfil_tipoMoneda(item);
perfiladapter.notifyDataSetChanged();
dialog.dismiss();
}
Hope it will work as you expect it to.
希望它会像你期望的那样工作。
回答by Kokusho
In my case i had to add this attribute in the listView :
就我而言,我必须在 listView 中添加此属性:
<ListView
...
android:clickable="true"
...
</ListView>
And in the adapter just add on click listener in the button view.
在适配器中,只需在按钮视图中添加单击侦听器。
wrapper.getButtonHi().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
DebugUtils.logDebug("Clickeado :: "+ mContact.getUserId());
}
});
Its important to set final the variables:
设置 final 变量很重要:
public View getRowView(final int position, View convertView, ViewGroup parent) {
final BrowseContactItemWrapper wrapper;
final UserModel mContact = lstContact.get(position);
.....
}
回答by Ronny Shibley
Just a small tweak to refresh the renderer from outside.
只是一个小的调整,从外部刷新渲染器。
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);