ScrollView嵌套ScrollView

大家好,众所周知,android 里两个相同方向的ScrollView是不能嵌套的,那要是有这样的需求怎么办?(这个需求一般都是不懂android的人提出来的)

难道就真的不能嵌套吗? 当然可以,只要你再写一个ScrollView,在里面做点脚,它就支持嵌套了。

目前做的这个只支持两个ScrollView嵌套,两个以上还有待改进,能套两个就已经能满足很多需求了,呵呵,另外现在只做了纵向scrollview的支持,横向的还没来的急做哦。

先上核心代码吧。代码里头我加了注释,方便大家阅读


package com.sun.shine.study.innerscrollview.view;

import android.content.Context;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.View;

import android.widget.ScrollView;

 

public class InnerScrollView extends ScrollView {


    /**

     */

    public ScrollView parentScrollView;

 
    public InnerScrollView(Context context, AttributeSet attrs) {

        super(context, attrs);

    }

    private int lastScrollDelta = 0;

 
    public void resume() {

        overScrollBy(0, -lastScrollDelta, 0, getScrollY(), 0, getScrollRange(), 0, 0, true);
        lastScrollDelta = 0;

    }

 

    int mTop = 10;

 

    /**
     * 将targetView滚到最顶端

     */

    public void scrollTo(View targetView) {

 

        int oldScrollY = getScrollY();

        int top = targetView.getTop() - mTop;

        int delatY = top - oldScrollY;

        lastScrollDelta = delatY;

        overScrollBy(0, delatY, 0, getScrollY(), 0, getScrollRange(), 0, 0, true);

    }

 

    private int getScrollRange() {

        int scrollRange = 0;

        if (getChildCount() > 0) {

            View child = getChildAt(0);

            scrollRange = Math.max(0, child.getHeight() - (getHeight()));

        }

        return scrollRange;

    }

    int currentY;

 

    @Override

    public boolean onInterceptTouchEvent(MotionEvent ev) {

        if (parentScrollView == null) {

            return super.onInterceptTouchEvent(ev);

        } else {

            if (ev.getAction() == MotionEvent.ACTION_DOWN) {

                // 将父scrollview的滚动事件拦截

                currentY = (int)ev.getY();

                setParentScrollAble(false);

                return super.onInterceptTouchEvent(ev);

            } else if (ev.getAction() == MotionEvent.ACTION_UP) {

                // 把滚动事件恢复给父Scrollview

                setParentScrollAble(true);

            } else if (ev.getAction() == MotionEvent.ACTION_MOVE) {


        }
        return super.onInterceptTouchEvent(ev); 

    }

 
    @Override

    public boolean onTouchEvent(MotionEvent ev) {

        View child = getChildAt(0);

        if (parentScrollView != null) {

            if (ev.getAction() == MotionEvent.ACTION_MOVE) {

                int height = child.getMeasuredHeight();

                height = height - getMeasuredHeight();

 

                // System.out.println("height=" + height);

                int scrollY = getScrollY();

                // System.out.println("scrollY" + scrollY);

                int y = (int)ev.getY();

 

                // 手指向下滑动

                if (currentY < y) {

                    if (scrollY <= 0) {

                        // 如果向下滑动到头,就把滚动交给父Scrollview

                        setParentScrollAble(true);

                        return false;

                    } else {

                        setParentScrollAble(false);

                    }

                } else if (currentY > y) {

                    if (scrollY >= height) {

                        // 如果向上滑动到头,就把滚动交给父Scrollview

                        setParentScrollAble(true);

                        return false;

                    } else {

                        setParentScrollAble(false);

 
                    }

                }

                currentY = y;

            }

        }

        return super.onTouchEvent(ev);

    }

 

    /**

     * 是否把滚动事件交给父scrollview

     * 

     * @param flag

     */

    private void setParentScrollAble(boolean flag) {

 

        parentScrollView.requestDisallowInterceptTouchEvent(!flag);

    }

 
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值