在android中ScrollView嵌套ScrollView

原文:

ScrollView嵌套ScrollView
http://www.eoeandroid.com/thread-240709-1-1.html

 

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

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

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

效果截图:

在android中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);

    }

 

}

 

 

 

 

 

你可能感兴趣的:(scrollview)