扩展HorizontalScrollView实现整个屏幕滚动

import java.lang.reflect.Field;   import android.content.Context;   import android.util.AttributeSet;   import android.view.animation.AnimationUtils;   import android.view.animation.Interpolator;   import android.view.animation.OvershootInterpolator;   import android.widget.HorizontalScrollView;   import android.widget.OverScroller;   import android.widget.Scroller;       public class HorizontalScrollViewEx extends HorizontalScrollView {         static final int ANIMATED_SCROLL_GAP = 250;      private long mLastScroll;      private Field mScrollerField;      ScrollerEx scrollerEx = null;         public HorizontalScrollViewEx(Context context) {            this(context, null);       }         public HorizontalScrollViewEx(Context context, AttributeSet attrs) {             super(context, attrs);          this.setSmoothScrollingEnabled(false);           initScroller();       }           public HorizontalScrollViewEx(Context context, AttributeSet attrs, int defStyle) {             super(context, attrs, defStyle);           this.setSmoothScrollingEnabled(false);           initScroller();         }        private void initScroller() {             try {                 mScrollerField = HorizontalScrollView.class.getDeclaredField("mScroller");               mScrollerField.setAccessible(true);               String type = mScrollerField.getType().getSimpleName();                 if ("OverScroller".equals(type)) {                     scrollerEx = new ScrollerEx() {                       private OverScroller mScroller = null;                         public void startScroll(int startX, int startY, int dx, int dy, int duration) {                           mScroller.startScroll(startX, startY, dx, dy, duration);                       }                         public boolean isFinished() {                          return mScroller.isFinished();                       }                         public Object getScroller() {                           return mScroller;                       }                         public void create(Context context, Interpolator interpolator) {                          mScroller = new OverScroller(context, interpolator);                       }                         public void abortAnimation() {                           if (mScroller != null) {                              mScroller.abortAnimation();                           }                       }                   };                 } else {                     scrollerEx = new ScrollerEx() {                       private Scroller mScroller = null;                         public void startScroll(int startX, int startY, int dx, int dy, int duration) {                          mScroller.startScroll(startX, startY, dx, dy, duration);                       }                           public boolean isFinished() {                          return mScroller.isFinished();                     }                         public Object getScroller() {                           return mScroller;                       }                         public void create(Context context, Interpolator interpolator) {                           mScroller = new Scroller(context, interpolator);                      }                         public void abortAnimation() {                           if (mScroller != null) {                                 mScroller.abortAnimation();                           }                       }                   };               }          } catch (Exception ex) {           }         }public final void smoothScrollBy(int dx, int dy, int addDuration) {             float tension = 0f;          scrollerEx.abortAnimation();           Interpolator ip = new OvershootInterpolator(tension);           scrollerEx.create(getContext(), ip);               try {               mScrollerField.set(this, scrollerEx.getScroller());           } catch (Exception e) {          }             long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;           if (duration > ANIMATED_SCROLL_GAP) {                 scrollerEx.startScroll(getScrollX(), getScrollY(), dx, dy, addDuration);              awakenScrollBars();                 // awakenScrollBars(mScroller.getDuration());              invalidate();           } else {                 if (!scrollerEx.isFinished()) {                   scrollerEx.abortAnimation();               }                 scrollBy(dx, dy);           }             mLastScroll = AnimationUtils.currentAnimationTimeMillis();      }         public final void smoothScrollTo(int x, int y, int duration) {          smoothScrollBy(x - getScrollX(), y - getScrollY(), duration);         }         private interface ScrollerEx {             void create(Context context, Interpolator interpolator);           Object getScroller();           void abortAnimation();           void startScroll(int startX, int startY, int dx, int dy, int duration);           boolean isFinished();       }   }   

核心部分是利用反射的方法取得父类的 mScroller对象,然后再使用 mScroller控制滚动。
然后在Activity里重写dispatchTouchEvent方法,使用GestureDetector控制滚动距离。 下面是部分代码

 
    private HorizontalScrollViewEx hsvMain;         @Override       public void onCreate(Bundle savedInstanceState) {             super.onCreate(savedInstanceState);            hsvMain = (HorizontalScrollViewEx) findViewById(R.id.hsvMain);             }         // 监听屏幕动作事件       GestureDetector =    gestureDetector = new GestureDetector(new OnGestureListener() {                 private int LEFT_DISTANCE = -150;               private int RIGHT_DISTANCE = 150;                 // 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发                 public boolean onDown(MotionEvent e) {                   return true;               }                 // 用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN,               // 多个ACTION_MOVE, 1个ACTION_UP触发               // e1:第1个ACTION_DOWN MotionEvent               // e2:最后一个ACTION_MOVE MotionEvent               // velocity X:X 轴上的移动速度,像素/秒              // velocity Y:Y 轴上的移动速度,像素/秒                 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {                       float distanceX = e2.getX() - e1.getX();                  if (distanceX < LEFT_DISTANCE) {                         // left                      setXPosition(true);                     } else if (distanceX > RIGHT_DISTANCE) {                         // right                       setXPosition(false);                     }                     hsvMain.smoothScrollTo(xPosition, 0, speed);                   return true;                 }              // 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发               public void onLongPress(MotionEvent e) {                 }               // 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE触发               public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {                     hsvMain.scrollBy((int) distanceX, 0);                   return true;                 }              // 用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEvent ACTION_DOWN触发               // 注意和onDown()的区别,强调的是没有松开或者拖动的状态                 public void onShowPress(MotionEvent e) {                 }               // 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发                 public boolean onSingleTapUp(MotionEvent e) {                     if (e.getY() < offsetOfBottom) {                       return true;                   }                     if (e.getX() > halfOfWidth) {                       setXPosition(true);                   } else {                         setXPosition(false);                     }                   hsvMain.scrollTo(xPosition, 0);                   return true;                 }           });        @Override         public boolean dispatchTouchEvent(MotionEvent ev) {           boolean result = gestureDetector.onTouchEvent(ev);             if (result == false) {               final int action = ev.getAction();               switch (action & MotionEvent.ACTION_MASK) {               case MotionEvent.ACTION_UP:                     hsvMain.smoothScrollTo(xPosition, 0, speed);                   result = true;               }             }           return true;         }   

效果:
第一页

你可能感兴趣的:(Android开发,移动开发,屏幕滚动)