[Android实例] [版主原创]ScrollView嵌套ScrollView

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

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

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

效果截图:


先上核心代码吧。代码里头我加了注释,方便大家阅读
代码片段,双击复制
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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、付费专栏及课程。

余额充值