ScrollView里嵌套ListView解决方案

ScrollView里嵌套ListView

开发中总是会遇到一些难以理解的需求,而我们却不得不去实现该功能,这次遇到的就是在ScrollView中嵌套个垂直的ListView,要说有必要这么做吗,listview本来不就可以上下拉么,只能说ScrollView里不只有ListView还有别的控件。以下对继承ListView的上拉加载下拉刷新都适用。因此,懂得事件分发机制很重要。

问题

ListView的高度

里面ListView的高度如何计算,通常只能显示ListView的其中一行,解决方法如下:自定义ListView重写onMeasure方法

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

ListView的滚动

ListView嵌套在ScrollView中不能滚动,我们就得从 Android事件的分发机制 下手了,要知道,子View可调用requestDisallowInterceptTouchEvent方法,来设置disallowIntercept=true,从而可以阻止父ViewGroup的onInterceptTouchEvent拦截操作。具体操作我们可通过个自定义ListView重写onInterceptTouchEvent方法,添加如下:

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
     switch (ev.getAction()) {
         case MotionEvent.ACTION_DOWN:
             setParentNoScrollAble(true);//当手指触到listview的时候,让父ScrollView交出ontouch权限,也就是让父scrollview 停住不能滚动
         case MotionEvent.ACTION_MOVE:
             break;
         case MotionEvent.ACTION_UP:
         case MotionEvent.ACTION_CANCEL:
             setParentNoScrollAble(false);//当手指松开时,让父ScrollView重新拿到onTouch权限
             break;
         default:
             break;
     }
     return super.onInterceptTouchEvent(ev);
  }

private void setParentNoScrollAble(boolean b) {
    // TODO Auto-generated method stub
    this.getParent().getParent().requestDisallowInterceptTouchEvent(b);

}

这样就可以实现当手触摸到该ListView时,让父容器ScrollView交出权限,当手指松开后,外面的ScrollView就重新获得权限,也就可以滑动外面了。这里还要注意一点,ListView最好设置个固定高度值,也可以按上面LIstView设置高度的操作。

ListView中CheckBox记住状态

我们如果把监听的代码放到设置checkbox状态的代码之后的话,仍然会 出现checkbox状态丢失的问题。这是为什么?viewholder会缓存item,所以如果监听写在后面的话,当初始化checkBox属性时,由于可能改变其状态,导致调用了onCheckedChange()方法,而这个监听器是在上一次初始化的时候添加的,那么position就是上一次的,不是本次的position,从而导致CheckBox中的状态错了。

CheckBox监听的代码块:

holder.my_CheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
       //进行选中状态的保存
    }
});

CheckBox设置状态:

holder.my_CheckBox.setChecked(obj.isChosen());//obj.isChosen()是获取选中的状态

总结:CheckBox设置状态 必须 写在CheckBox监听的代码块 后面

参考链接

http://blog.csdn.net/hj363049394/article/details/26590079#
http://blog.csdn.net/footballclub/article/details/43123105

你可能感兴趣的:(Android基础)