如何响应ListView的内部按钮的点击事件呢?比如说listView上的item有一个ImageView控件,我要获取对应每个ImageView控件的点击事件,较为常见的办法是在自定义的adapter中的getView方法内为每个ImageView绑定监听器。当然这种方法能满足大部分的使用情况了,但某些情况下要在activity内获取点击事件下面给出方法。
</pre></p><p></p><p> 先上代码:(共四个文件)</p><p> 先看布局(尽量最简化啦)</p><p> activity_main.xml(主布局文件)<pre name="code" class="html"><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" > </ListView> </RelativeLayout>item.xml(item布局)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="40dp" android:orientation="vertical" > <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center" android:src="@drawable/contact" /> </LinearLayout>MainActivity.java(activity文件)
package com.developmc.listview; import java.util.ArrayList; import java.util.List; import com.developmc.listview.MyAdapter.MyCallBack; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.ListView; import android.widget.Toast; public class MainActivity extends Activity implements MyCallBack { private ListView listView ; private List<String> lists ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView=(ListView)findViewById(R.id.listView) ; lists = new ArrayList<String>() ; for(int i=0;i<20;i++) { lists.add(i+"") ; } //若在fragment中定义的listView,将第一个this替换成getContext() MyAdapter adapter = new MyAdapter(this,lists,this) ; listView.setAdapter(adapter); } @Override public void onItemWidgetClickListener(View v) { //item上有多个可点击的控件时,根据控件id找到相应事件(这里只有一个控件) switch (v.getId()) { case R.id.imageView: Toast.makeText(this, "回调成功 ", Toast.LENGTH_SHORT).show(); break; default: break; } } }MyAdapter.java(自定义的适配器)
package com.developmc.listview; import java.util.List; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.Toast; public class MyAdapter extends BaseAdapter implements OnClickListener { private Context context ; private List<String> lists ; private MyCallBack mCallBack ; public MyAdapter(Context context,List<String> lists,MyCallBack mCallBack) { this.context=context ; this.lists=lists ; this.mCallBack = mCallBack ; } @Override public int getCount() { // TODO Auto-generated method stub return lists.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return lists.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) { // TODO Auto-generated method stub ViewHolder viewHolder = null ; if(convertView==null) { viewHolder = new ViewHolder() ; convertView = LayoutInflater.from(context).inflate(R.layout.item, null) ; viewHolder.imageView = (ImageView)convertView.findViewById(R.id.imageView) ; convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder)convertView.getTag() ; } viewHolder.imageView.setOnClickListener(this); // viewHolder.imageView.setOnClickListener(new OnClickListener() { // // @Override // public void onClick(View v) { // // TODO Auto-generated method stub // Toast.makeText(context, " "+position, Toast.LENGTH_SHORT).show(); // } // }); return convertView; } //定义回调接口 public interface MyCallBack { //listView item下的控件点击事件(注意传入参数V) public void onItemWidgetClickListener(View v) ; } @Override public void onClick(View v) { //在onClick中回调接口的OnItemClickListener mCallBack.onItemWidgetClickListener(v); } private class ViewHolder{ private ImageView imageView ; } }上面就是所有代码了,这里就已经实现在Activity或fragment中响应ListView内部按钮的点击事件。下面逐步分解过程:
1.依旧需要在adapter的getView下绑定控件监听器:
viewHolder.imageView.setOnClickListener(this); 让adapter继承OnClickListener,系统生成Onclick方法。
2.自定义一个回调接口:这里记得要将参数view
//定义回调接口
public interface MyCallBack
{
//listView item下的控件点击事件(注意传入参数V)
public void onItemWidgetClickListener(View v) ;
}
3.在Onclick中调用自定义的接口,传入view。需要先在构造函数获得接口对象。
mCallBack.onItemWidgetClickListener(v);
4.让MainActivity.java继承MyCallBack接口。
5.实现onItemWidgetClickListener(v);接口,在里边实现响应的点击事件。至此已经完成。
不足之处:通过此方法能够实现在activity或fragmen中响应内部listView控件的点击事件(可以通过为控件添加selector文件观察控件是否被点击),但无法通过回调得到点击控件所在的item位置,这是因为在geiview中position只在listView绘制的时候才会变动,相对于在getView中实现点击事件来说,如此回调不能将每次的位置的信息都回调。虽然,listView有onItemClickListener方法,然而并没有什么卵用。
总结:相对于常规的在geiView中实现控件的的点击事件,本文给出的方法能够现实,但不足之处(或许致命)是无法通过回调得到点击控件所在的item位置,引用老罗的话,生命不息,折腾不止啊!