• 扩展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;
     
        }
     

    效果:
    第一页

  • 相关阅读:
    人不成熟的六个特征
    qq申请器,有源码,用post提交
    有的公司,在不断创新,我们时刻能感受到
    Java中 堆 栈,常量池等概念解析(转载)
    Jquery获得相同id的元素
    强大Jquery插件,table排序
    和计算机沟通
    千万级架构设计诀窍(zz)(
    强大Jquery插件,table排序之二
    原文作者乔纳森·丹尼可(Jonathan Danylko)是一位自由职业的web架构师和程序员,编程经验已超过20年,涉足领域有电子商务、生物技术、房地产、医疗、保险和公用事业。正如乔纳 森在文中所言,本文适合刚毕业的大学生和刚入门的程序员。如果你已是高级
  • 原文地址:https://www.cnblogs.com/vus520/p/2561951.html
Copyright © 2020-2023  润新知