ScrollView嵌套ScrollView

实现嵌套ScrollView的技巧
本文介绍了一种方法,通过自定义ScrollView类实现两个ScrollView的嵌套,支持纵向滚动,并提供核心代码及使用说明。

From:http://www.eoeandroid.com/thread-240709-1-1.html

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

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

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

效果截图:


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

001 package com.sun.shine.study.innerscrollview.view;
002  
003 import android.content.Context;
004 import android.util.AttributeSet;
005 import android.view.MotionEvent;
006 import android.view.View;
007 import android.widget.ScrollView;
008  
009 public class InnerScrollView extends ScrollView {
010  
011     /**
012      */
013     public ScrollView parentScrollView;
014  
015     public InnerScrollView(Context context, AttributeSet attrs) {
016         super(context, attrs);
017  
018     }
019  
020     private int lastScrollDelta = 0;
021  
022     public void resume() {
023         overScrollBy(0, -lastScrollDelta, 0, getScrollY(), 0, getScrollRange(), 0, 0, true);
024         lastScrollDelta = 0;
025     }
026  
027     int mTop = 10;
028  
029     /**
030      * 将targetView滚到最顶端
031      */
032     public void scrollTo(View targetView) {
033  
034         int oldScrollY = getScrollY();
035         int top = targetView.getTop() - mTop;
036         int delatY = top - oldScrollY;
037         lastScrollDelta = delatY;
038         overScrollBy(0, delatY, 0, getScrollY(), 0, getScrollRange(), 0, 0, true);
039     }
040  
041     private int getScrollRange() {
042         int scrollRange = 0;
043         if (getChildCount() > 0) {
044             View child = getChildAt(0);
045             scrollRange = Math.max(0, child.getHeight() - (getHeight()));
046         }
047         return scrollRange;
048     }
049  
050     int currentY;
051  
052     @Override
053     public boolean onInterceptTouchEvent(MotionEvent ev) {
054         if (parentScrollView == null) {
055             return super.onInterceptTouchEvent(ev);
056         } else {
057             if (ev.getAction() == MotionEvent.ACTION_DOWN) {
058                 // 将父scrollview的滚动事件拦截
059                 currentY = (int)ev.getY();
060                 setParentScrollAble(false);
061                 return super.onInterceptTouchEvent(ev);
062             } else if (ev.getAction() == MotionEvent.ACTION_UP) {
063                 // 把滚动事件恢复给父Scrollview
064                 setParentScrollAble(true);
065             } else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
066             }
067         }
068         return super.onInterceptTouchEvent(ev);
069  
070     }
071  
072     @Override
073     public boolean onTouchEvent(MotionEvent ev) {
074         View child = getChildAt(0);
075         if (parentScrollView != null) {
076             if (ev.getAction() == MotionEvent.ACTION_MOVE) {
077                 int height = child.getMeasuredHeight();
078                 height = height - getMeasuredHeight();
079  
080                 // System.out.println("height=" + height);
081                 int scrollY = getScrollY();
082                 // System.out.println("scrollY" + scrollY);
083                 int y = (int)ev.getY();
084  
085                 // 手指向下滑动
086                 if (currentY < y) {
087                     if (scrollY <= 0) {
088                         // 如果向下滑动到头,就把滚动交给父Scrollview
089                         setParentScrollAble(true);
090                         return false;
091                     } else {
092                         setParentScrollAble(false);
093  
094                     }
095                 } else if (currentY > y) {
096                     if (scrollY >= height) {
097                         // 如果向上滑动到头,就把滚动交给父Scrollview
098                         setParentScrollAble(true);
099                         return false;
100                     } else {
101                         setParentScrollAble(false);
102  
103                     }
104  
105                 }
106                 currentY = y;
107             }
108         }
109  
110         return super.onTouchEvent(ev);
111     }
112  
113     /**
114      * 是否把滚动事件交给父scrollview
115      *
116      * @param flag
117      */
118     private void setParentScrollAble(boolean flag) {
119  
120         parentScrollView.requestDisallowInterceptTouchEvent(!flag);
121     }
122  
123 }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值