Android中ListView实现子控件点击事件后ListView点击事件失效解决办法

最近有人问我,在Android里:

在自定义listView里面有按钮,然后setItemClickListener时不响应,网上很多关于这个的,但我都试过,貌似都解决不了。
其实刚开始学Android接触ListView时我也遇到此问题,在网上到处搜也难以找到相关解决方案,原因之一是网上原创文章少,转载居多,很多文章都雷同;原因之二在于自己英语不好,不敢上外文论坛去找。
后来经过自己的慢慢摸索终于解决了这个问题。
当朋友问我时,我一番简单讲解加几张代码截图就给他解决问题啦~
废话不多说,先上源代码: 源代码
代码片段:
main.xml
<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"
    android:background="@drawable/background" >

    <ListView
        android:id="@+id/lv_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/numxback"
        android:cacheColorHint="#00000000"
        android:drawSelectorOnTop="false"
        android:fadingEdge="none"
        android:fastScrollEnabled="true"
        android:focusable="false"
        android:divider="@null"
        android:focusableInTouchMode="true"
        android:listSelector="@drawable/itemselected" />

</RelativeLayout>
在main布局里加入了一个列表控件,ListView,它的各个属性在此处不是重点,这里就不多说,看不懂的读者自己去网上搜吧!
datalist.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/widget_datalist"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:descendantFocusability="blocksDescendants">

    <TextView
        android:id="@+id/tv_num"
        android:layout_width="wrap_content"
        android:layout_height="60px"
        android:layout_centerVertical="true"
        android:background="@drawable/number"
        android:gravity="center"
        android:paddingLeft="5px"
        android:paddingRight="8px"
        android:textColor="@android:color/white"
        android:textSize="24sp" />

    <ImageButton
        android:id="@+id/ib_edit"
        android:layout_width="60px"
        android:layout_height="60px"
        android:layout_alignParentRight="true"
        android:background="@drawable/edit"
        <span style="color:#ff0000">android:onClick="OnItemEditClick"
</span>        android:paddingRight="5px" />

    <TextView
        android:id="@+id/tv_numx"
        android:layout_width="150px"
        android:layout_height="60px"
        android:layout_toRightOf="@+id/tv_num"
        android:background="@drawable/number"
        android:gravity="center_vertical"
        android:singleLine="true"
        android:textColor="@android:color/white"
        android:textSize="24sp" />

    <TextView
        android:id="@+id/tv_numy"
        android:layout_width="150px"
        android:layout_height="60px"
        android:layout_toRightOf="@id/tv_numx"
        android:layout_toLeftOf="@id/ib_edit"
        android:background="@drawable/number"
        android:gravity="center_vertical"
        android:singleLine="true"
        android:textColor="@android:color/white"
        android:textSize="24sp" />

</RelativeLayout>
列表控件单独布局,在里面加入了三个TextView,一个ImageButton,显示时三个TextView 在前面,最后一个ImageButton。
之前说到的按钮点击事件在Activity里用button.setOnClickListener的方式实现时会屏蔽/占用ListView单项单击事件,这里就在布局里加了一个 android:onClick="OnItemEditClick" ,用于绑定按钮点击事件,然后在java代码中实现这个方法,记得须有一个 View类型的参数
MainActivity.java
package com.test.customlistview;

import java.util.ArrayList;
import java.util.HashMap;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemLongClickListener;

public class MainActivity extends Activity {
	
	ListView dataListView;
	SimpleAdapter listAdapter;
	ArrayList<HashMap<String, Object>> list;
	private int location;
	Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			if (msg.arg1 == 1) {

			} else if (msg.arg1 == 2) {

			} else if (msg.arg1 == 4) {
				if (msg.what == 1) {
					dataListView.getChildAt(msg.arg2).setBackgroundResource(
							R.drawable.itemback);
				}
			}
			super.handleMessage(msg);
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		dataListView = (ListView) findViewById(R.id.lv_list);
		list = new ArrayList<HashMap<String, Object>>();
		int count = 20;
		HashMap<String, Object> map;
		for (int i = 1; i <= count; i++) {
			map = new HashMap<String, Object>();
			map.put("num", i+ "");
			map.put("a1", "²=");
			map.put("a2", ""+i*i);
			list.add(map);
		}
		listAdapter = new SimpleAdapter(this, list, R.layout.datalist,
				new String[] { "num", "a1", "a2" }, new int[] { R.id.tv_num,
						R.id.tv_numx, R.id.tv_numy });
		dataListView.setAdapter(listAdapter);
		dataListView.setOnItemLongClickListener(new OnItemLongClickListener() {
			public boolean onItemLongClick(AdapterView<?> arg0, View view,
					int position, long id) {
				location = position;
				final View nowView = (View) view.findViewById(R.id.ib_edit);
				Toast.makeText(getBaseContext(), "location=" + location, 2000)
						.show();
				OnClickListener listener = new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						if (which == 0) {
							Toast.makeText(getBaseContext(), "编辑", Toast.LENGTH_LONG).show();
						} else if (which == 1) {
							Toast.makeText(getBaseContext(), "删除", Toast.LENGTH_LONG).show();
						}
					}
				};
				dataListView.getChildAt(location).setBackgroundResource(
						R.drawable.item_frame);
				Message message = new Message();
				message.arg1 = 4;
				message.arg2 = location;
				message.what = 1;
				mHandler.sendMessageDelayed(message, 500);
				String[] Menu = { "编辑", "删除" };
			
				new AlertDialog.Builder(MainActivity.this).setItems(Menu,
						listener).show();
				return false;
			}
		});
	}
	
	public void OnItemEditClick(View v) {
		RelativeLayout layout = (RelativeLayout) v.getParent();
		TextView tv1=(TextView)layout.findViewById(R.id.tv_num);
		TextView tv2=(TextView)layout.findViewById(R.id.tv_numx);
		TextView tv3=(TextView)layout.findViewById(R.id.tv_numy);
		ImageButton ib=(ImageButton)layout.findViewById(R.id.ib_edit);
		String str="按钮"+tv1.getText()+"点击啦\n"+tv1.getText()+tv2.getText()+tv3.getText();
		Toast.makeText(getBaseContext(), str, Toast.LENGTH_LONG).show();
	}
}
OnItemEditClick(View v)方法中通过v.getParent();找到她的容器控件,前面的(RelativeLayout)根据你自己的布局里的容器控件而定。然后即可使用该容器控件找到他的所有自控件,然后读者想干嘛就干嘛啦~
上面的dataListView.setOnItemLongClickListener实现ListView的item长按事件,我在这里加了一个显示两条菜单的对话框,用于进行其他操作,如编辑、删除等。
这里也可以实现ListView的点击事件,PS:这段代码是后来加的,直接嵌入源代码中即可,已调试无误。
 
dataListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View view, int arg2,
					long arg3) {
				TextView tv=(TextView)view.findViewById(R.id.tv_num);
				Toast.makeText(getBaseContext(), "您点击了第" + tv.getText()+"行", 2000).show();
			}
		});
修改后的MainActivity.java代码如下
package com.test.customlistview;

import java.util.ArrayList;
import java.util.HashMap;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemLongClickListener;

public class MainActivity extends Activity {
	
	ListView dataListView;
	SimpleAdapter listAdapter;
	ArrayList<HashMap<String, Object>> list;
	private int location;
	Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			if (msg.arg1 == 1) {

			} else if (msg.arg1 == 2) {

			} else if (msg.arg1 == 4) {
				if (msg.what == 1) {
					dataListView.getChildAt(msg.arg2).setBackgroundResource(
							R.drawable.itemback);
				}
			}
			super.handleMessage(msg);
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		dataListView = (ListView) findViewById(R.id.lv_list);
		list = new ArrayList<HashMap<String, Object>>();
		int count = 20;
		HashMap<String, Object> map;
		for (int i = 1; i <= count; i++) {
			map = new HashMap<String, Object>();
			map.put("num", i+ "");
			map.put("a1", "²=");
			map.put("a2", ""+i*i);
			list.add(map);
		}
		listAdapter = new SimpleAdapter(this, list, R.layout.datalist,
				new String[] { "num", "a1", "a2" }, new int[] { R.id.tv_num,
						R.id.tv_numx, R.id.tv_numy });
		dataListView.setAdapter(listAdapter);
		dataListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View view, int arg2,
					long arg3) {
				TextView tv=(TextView)view.findViewById(R.id.tv_num);
				Toast.makeText(getBaseContext(), "您点击了第" + tv.getText()+"行", 2000).show();
			}
		});
		dataListView.setOnItemLongClickListener(new OnItemLongClickListener() {
			public boolean onItemLongClick(AdapterView<?> arg0, View view,
					int position, long id) {
				location = position;
				final View nowView = (View) view.findViewById(R.id.ib_edit);
				Toast.makeText(getBaseContext(), "location=" + location, 2000)
						.show();
				OnClickListener listener = new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						if (which == 0) {
							Toast.makeText(getBaseContext(), "编辑", Toast.LENGTH_LONG).show();
						} else if (which == 1) {
							Toast.makeText(getBaseContext(), "删除", Toast.LENGTH_LONG).show();
						}
					}
				};
				dataListView.getChildAt(location).setBackgroundResource(
						R.drawable.item_frame);
				Message message = new Message();
				message.arg1 = 4;
				message.arg2 = location;
				message.what = 1;
				mHandler.sendMessageDelayed(message, 500);
				String[] Menu = { "编辑", "删除" };
			
				new AlertDialog.Builder(MainActivity.this).setItems(Menu,
						listener).show();
				return false;
			}
		});
	}
	
	public void OnItemEditClick(View v) {
		RelativeLayout layout = (RelativeLayout) v.getParent();
		TextView tv1=(TextView)layout.findViewById(R.id.tv_num);
		TextView tv2=(TextView)layout.findViewById(R.id.tv_numx);
		TextView tv3=(TextView)layout.findViewById(R.id.tv_numy);
		ImageButton ib=(ImageButton)layout.findViewById(R.id.ib_edit);
		String str="按钮"+tv1.getText()+"点击啦\n"+tv1.getText()+tv2.getText()+tv3.getText();
		Toast.makeText(getBaseContext(), str, Toast.LENGTH_LONG).show();
	}
}

注:这个小demo根本算不上自定义ListView,只是稍微给他丰富了一下子元素,以实现更好看的界面效果,当然,我这个不好看哈,只是为了写博文的演示罢了。
运行截图:
截图一 截图二  截图三
 
代码都贴出来了,说明文字不多,但应该基本说清楚了,读者慢慢看吧,主要还是研读代码,尝试着慢慢修改变成自己的并从中学到一些东西才是重点!
 
一如既往,欢迎广大读者提出批评及改进意见,我一定会不断努力的~

我的QQ:1239848066

反馈请猛戳:

原创博客:转载后记得附带原文链接,谢谢~


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值