Android ListView中Item点击事件失效解决方案

在平常的开发过程中,我们的ListView可能不只是简单的显示下文本或者按钮,更多的是显示复杂的布局,这样的话,我们就得自己写布局和自定义adapter了,一般是继承于BaseAdapter,示例代码见下方。写ListView的点击事件时OnItemClickListener,onItemClick方法没有执行,导致ListView中Item条目点击事件失效,而Item中的View点击事件可以在getView方法中进行处理。导致整个Item点击失效的原因多半是由于在你自己定义的Item中存在诸如ImageButton,Button,CheckBox等子控件(也可以说是Button或者Checkable的子类控件),此时这些子控件会将焦点获取到,所以常常当点击item时变化的是子控件,item本身的点击没有响应。

这时候就可以使用descendantFocusability来解决,其中descendantFocusability对应的属性有3个

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

属性的值有三种:

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

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

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

  解决方法

 1、通常我们用到的是第三种,即在Item布局的根布局加上android:descendantFocusability=”blocksDescendants”的属性就好了。

       ps:有时我们的List也不想显示出分割线时,可以通过以下属性来设置:

android:divider="#00000000"  
android:dividerHeight="0dip" 

  2、被点击的控件如ImageButton中添加属性android:focusable="false"

优化的listView代码写法

import java.util.ArrayList;
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.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MyAdapter extends BaseAdapter {
	private Context mContext;
	private List mList = new ArrayList();

	public MyAdapter(Context mContext, List mList) {
		super();
		this.mContext = mContext;
		this.mList = mList;
	}

	@Override
	public int getCount() {
		// TODO 自动生成的方法存根
		return mList.size();
	}

	@Override
	public Object getItem(int position) {
		// TODO 自动生成的方法存根
		return mList.get(position);
	}

	@Override
	public long getItemId(int position) {
		// TODO 自动生成的方法存根
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		final ViewHolder viewHolder;
		final int index=position;
		if (convertView == null) {
			viewHolder = new ViewHolder();
			convertView = LayoutInflater.from(mContext).inflate(
					R.layout.list_item, null);
			viewHolder.tv1 = (TextView) convertView.findViewById(R.id.tv1);
			viewHolder.tv2 = (TextView) convertView.findViewById(R.id.tv2);
			viewHolder.tv3 = (TextView) convertView.findViewById(R.id.tv3);
			viewHolder.bt1 = (Button) convertView.findViewById(R.id.bt1);
			viewHolder.bt2 = (Button) convertView.findViewById(R.id.bt2);
			
			convertView.setTag(viewHolder);
		} else {
			viewHolder = (ViewHolder) convertView.getTag();
		}
		// 用bean 来填充数据
        viewHolder.tv1.setText(mList.get(position).getErrorContent());
        viewHolder.tv2.setText(mList.get(position).getRightAns());
        viewHolder.tv3.setText(mList.get(position).getErrorSolution());
		viewHolder.bt1.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO 自动生成的方法存根
				viewHolder.tv3.setText(mList.get(index).getErrorSolution());
				Toast.makeText(mContext, "" + v.getId(), 0).show();
			}
		});
		viewHolder.bt2.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO 自动生成的方法存根
				viewHolder.tv3.setText(mList.get(index).getErrorPrompt());
				Toast.makeText(mContext, "" + v.getId(), 0).show();
			}
		});
		return convertView;
	}

	final static class ViewHolder {
		TextView tv1, tv2,tv3;
		Button bt1, bt2;
	}
}

有时一些代码段真的很容易忘记,比如常用的ScrollView嵌套listView的,要屏蔽listview的滑动

public class ListViewNoScroll extends ListView {
    public ListViewNoScroll(Context context) {
        super(context);
    }

    public ListViewNoScroll(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }

}

这篇文章写的有点乱了,好吧,主要是为了防止忘记和以后查找方便,关于listview的注意事项也都写在这吧


你可能感兴趣的:(Android)