在Activity或fragment中响应ListView内部控件的点击事件

            如何响应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位置,引用老罗的话,生命不息,折腾不止啊!



你可能感兴趣的:(ListView,控件点击)