如何在listview中添加button,使得listview item 和 button获取焦点不冲突

在自定义ListView时,如果Item中包含Button等可聚焦控件,可能导致点击Item无响应。通过设置`android:descendantFocusability`属性为`blocksDescendants`,可以确保ListView Item获取焦点,而不是其子元素。只需在Item布局中添加`android:focusable="false"`到Button,并在Adapter中为Button设置点击监听。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

listview item 的布局如下所示:


代码如下所示:


<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" 
    android:descendantFocusability="blocksDescendants">

    <TableRow
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <ImageView
            android:id="@+id/iv_appIcon"
            android:layout_width="0dp"
            android:layout_height="65dp"
            android:layout_weight="1"
            android:contentDescription="@string/Static_iv_appIcon"
            android:src="@drawable/default_app_icon" />

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_weight="3"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/running_progress_tv_app_name"
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:layout_marginTop="7dp"
                android:text="@string/tv_running_progress_app_name"
                android:textSize="23sp" />

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal" >

                <TextView
                    android:id="@+id/running_progress_tv_single_memsize"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="5dp"
                    android:text="@string/tv_running_progress_single_memsize"
                    android:textSize="13sp" />

                <TextView
                    android:id="@+id/running_progress_tv_protected_by_whitelist"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="5dp"
                    android:text="@string/tv_running_progress_protected_by_whitelist"
                    android:textSize="13sp" />
            </LinearLayout>
        </LinearLayout>
        <Button 
            android:id="@+id/running_progress_bt_stop"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.8"
            android:text="@string/static_bt_running_progress_stop"
            android:layout_gravity="center"
            android:focusable="false"
            />
    </TableRow>

</TableLayout>

其中,在TableLayout中要添加 android:descendantFocusability="blocksDescendants"

且,在Button控件中添加android:focusable="false"这个属性即可。

具体Adapter中对button添加setOnClickListener即可,具体代码如下:

package com.alibaba.memoryspeedup;

import java.lang.reflect.Field;
import java.util.List;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class RunningProgressListViewAdapter extends BaseAdapter {
	private String TAG = "RunningProgressListViewAdapter";
	private Context mContext;
	private PackageManager packageManager = null;
	private ApplicationInfo applicationInfo = null;
	private List<RunningProgressListItem> mRunningProgressList;
	public RunningProgressListViewAdapter(Context mContext,
			List<RunningProgressListItem> mRunningProgressList) {
		super();
		this.mContext = mContext;
		this.mRunningProgressList = mRunningProgressList;
	}
	
	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return mRunningProgressList.size();
	}

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		
		final RunningProgressListItem rpli = mRunningProgressList.get(position);
		ViewHolder holder;
		if (convertView == null) {
			Log.i(TAG,"new ViewHolder()"); 
			convertView = View.inflate(mContext, R.layout.running_progress_listview_item, null);
			holder = new ViewHolder();
			holder.iv_appIcon = (ImageView) convertView.findViewById(R.id.iv_appIcon);
			holder.tv_appName = (TextView) convertView.findViewById(R.id.running_progress_tv_app_name);
			holder.tv_memSize = (TextView) convertView.findViewById(R.id.running_progress_tv_single_memsize);
			holder.bt_stop = (Button) convertView.findViewById(R.id.running_progress_bt_stop);
			convertView.setTag(holder);
		}
		else {
			holder = (ViewHolder) convertView.getTag();
		}
		
		//View view = View.inflate(mContext, R.layout.running_progress_listview_item, null);
		/*ImageView iv_appIcon = (ImageView) convertView.findViewById(R.id.iv_appIcon);
		TextView tv_appName = (TextView) convertView.findViewById(R.id.running_progress_tv_app_name);
		TextView tv_memSize = (TextView) convertView.findViewById(R.id.running_progress_tv_single_memsize);*/
		
		try {
			packageManager = mContext.getPackageManager();
			applicationInfo = packageManager.getApplicationInfo(rpli.getPackageName(), PackageManager.GET_META_DATA);
		} catch (PackageManager.NameNotFoundException e) {
			applicationInfo = null;
			e.printStackTrace();
		}
		Drawable appIcon = packageManager.getApplicationIcon(applicationInfo);
		
		holder.iv_appIcon.setImageDrawable(appIcon);
		holder.tv_appName.setText(rpli.getAppName());
		holder.tv_memSize.setText(rpli.getMemSize()+" Kb");
		holder.bt_stop.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Toast.makeText(mContext,"Process Killed : " + rpli.getAppName()  ,Toast.LENGTH_LONG).show();
			}
		});
		
		return convertView;
	}
	static class ViewHolder {
		ImageView iv_appIcon;
		TextView tv_appName;
		TextView tv_memSize;
		Button bt_stop;
		
		}

}

下面资料供大家参考:(参考 Mr梵谷 ,  android:descendantFocusability用法分析

    开发中很常见的一个问题,项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现了,可能会发生点击每一个item的时候没有反应,无法获取的焦点。原因多半是由于在你自己定义的Item中存在诸如ImageButton,Button,CheckBox等子控件(也可以说是Button或者Checkable的子类控件),此时这些子控件会将焦点获取到,所以常常当点击item时变化的是子控件,item本身的点击没有响应。

    这时候就可以使用descendantFocusability来解决啦,API描述如下:

android:descendantFocusability

Defines the relationship between the ViewGroup and its descendants when looking for a View to take focus.

Must be one of the following constant values.

 

该属性是当一个为view获取焦点时,定义viewGroup和其子控件两者之间的关系。

属性的值有三种:

        beforeDescendants:viewgroup会优先其子类控件而获取到焦点

        afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点

        blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值