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

被折叠的 条评论
为什么被折叠?



