新手上路,scrollview 嵌套listview scrollview嵌套scrollview滑动冲突等问题的学习

记录自己学习的点滴!!

ScrollView里套ScrollView和ScrollView里套ListView是同一个道理的。

按常理,ScrollView套ListView会存在两个问题:

1.里面的listView高度无法算出来,通常只能显示listview的其中一行
2.listview不能滚动

其实实现原理很简单ScrollView有一个方法requestDisallowInterceptTouchEvent(boolean);
这个方法是设置是否交出ontouch权限的,如果让外层的scrollview.requestDisallowInterceptTouchEvent(false);那么外层的onTouch权限会失去,这样里面的listview就能
拿到ontouch权限了,listView也就能滚了。
问题是:权限只有一个,要支持两个view都能滚动。这个就有点难实现了吧..

其实这个一点也不难,当手指触到listview的时候,让外面的scrollview交出权限,当手指松开后,外面的scrollview重新获得权限。这样ok了。

代码实现:
重写一个InnerListView extends ListView

InnerListView.java

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


  /**
     * 是否把滚动事件交给父scrollview
     * 
     * @param flag
     */
    private void setParentScrollAble(boolean flag) {
       parentScrollView.requestDisallowInterceptTouchEvent(!flag);//这里的parentScrollView就是listview外面的那个scrollview
    }

在这里我要提出的是,listview能滚动的前提是:当listview本身的高度小于listview里的子view。

如果在xml里让listview的高度为wrap_content,可能会出现问题,如:ListView的高度会变成跟子view 的高度一样。

这里最好是让listView的高度固定,平时我们写listView布局的时候也是给一个固定值。如fill_parent或100dip

我写了一个参数叫maxHeight.设置listview的最大高度。是为了确保ListView的高度固定。

   private int maxHeight;
    public int getMaxHeight() {
        return maxHeight;
    }
    public void setMaxHeight(int maxHeight) {
        this.maxHeight = maxHeight;
    }
@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        if (maxHeight > -1) {
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        System.out.println(getChildAt(0));
    }

源代码


在适配不同的屏幕时,代码中设置的setMaxHeight,可根据获取屏幕高宽来设置

private int getMaxHeight() {
DisplayMetrics metric = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels; // 屏幕宽度(像素)
int height = metric.heightPixels; // 屏幕高度(像素)
float density = metric.density; // 屏幕密度(0.75 / 1.0 / 1.5)
int densityDpi = metric.densityDpi; // 屏幕密度DPI(120 / 160 / 240)
return (int) (0.18 * height);

}

0.18是通过计算你控件 listview的高度/height 的比例,不同的手机不同的高度,但是listview占整个屏幕的比例都是相差很小

然后setMaxHeight(getMaxHeight()); 就能适配不同的屏幕




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值