原文:
ScrollView嵌套ScrollView
http://www.eoeandroid.com/thread-240709-1-1.html
大家好,眾所周知,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); } }