在平常的开发过程中,我们的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<ErrorDataBean> mList = new ArrayList<ErrorDataBean>();
-
- public MyAdapter(Context mContext, List<ErrorDataBean> mList) {
- super();
- this.mContext = mContext;
- this.mList = mList;
- }
-
- @Override
- public int getCount() {
-
- return mList.size();
- }
-
- @Override
- public Object getItem(int position) {
-
- return mList.get(position);
- }
-
- @Override
- public long getItemId(int position) {
-
- 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();
- }
-
- 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) {
-
- 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) {
-
- 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);
- }
-
- }