• Android Scroller简单用法


    1.知识点

    在了解Scorller类之前应先知道View的ScrollTo(int x, int y)/ScrollBy(int x, int y)之间的区别,了解什么是视图坐标,什么是布局坐标。之后我们来看一下Scroller的源码

    Scoller一般用在自定义View中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    public class Scroller  { 
       
        private int mStartX;    //起始坐标点 ,  X轴方向 
        private int mStartY;    //起始坐标点 ,  Y轴方向 
        private int mCurrX;     //当前坐标点  X轴, 即调用startScroll函数后,经过一定时间所达到的值 
        private int mCurrY;     //当前坐标点  Y轴, 即调用startScroll函数后,经过一定时间所达到的值 
          
        private float mDeltaX;  //应该继续滑动的距离, X轴方向 
        private float mDeltaY;  //应该继续滑动的距离, Y轴方向 
        private boolean mFinished;  //是否已经完成本次滑动操作, 如果完成则为 true 
       
        //构造函数 
        public Scroller(Context context) { 
            this(context, null); 
        
        public final boolean isFinished() { 
            return mFinished; 
        
        //强制结束本次滑屏操作 
        public final void forceFinished(boolean finished) { 
            mFinished = finished; 
        
        public final int getCurrX() { 
            return mCurrX; 
        
         /* Call this when you want to know the new location.  If it returns true,
         * the animation is not yet finished.  loc will be altered to provide the
         * new location. */   
        //根据当前已经消逝的时间计算当前的坐标点,保存在mCurrX和mCurrY值中 
        public boolean computeScrollOffset() { 
            if (mFinished) {  //已经完成了本次动画控制,直接返回为false 
                return false
            
            int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime); 
            if (timePassed < mDuration) { 
                switch (mMode) { 
                case SCROLL_MODE: 
                    float x = (float)timePassed * mDurationReciprocal; 
                    ... 
                    mCurrX = mStartX + Math.round(x * mDeltaX); 
                    mCurrY = mStartY + Math.round(x * mDeltaY); 
                    break
                ... 
            
            else
                mCurrX = mFinalX; 
                mCurrY = mFinalY; 
                mFinished = true
            
            return true
        
        //开始一个动画控制,由(startX , startY)在duration时间内前进(dx,dy)个单位,即到达坐标为(startX+dx , startY+dy)出 
        public void startScroll(int startX, int startY, int dx, int dy, int duration) { 
            mFinished = false
            mDuration = duration; 
            mStartTime = AnimationUtils.currentAnimationTimeMillis(); 
            mStartX = startX;       mStartY = startY; 
            mFinalX = startX + dx;  mFinalY = startY + dy; 
            mDeltaX = dx;            mDeltaY = dy; 
            ... 
        
    }

    一些方法介绍

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    mScroller.getCurrX() //获取mScroller当前水平滚动的位置 
    mScroller.getCurrY() //获取mScroller当前竖直滚动的位置 
    mScroller.getFinalX() //获取mScroller最终停止的水平位置 
    mScroller.getFinalY() //获取mScroller最终停止的竖直位置 
    mScroller.setFinalX(int newX) //设置mScroller最终停留的水平位置,没有动画效果,直接跳到目标位置 
    mScroller.setFinalY(int newY) //设置mScroller最终停留的竖直位置,没有动画效果,直接跳到目标位置 
       
    //滚动,startX, startY为开始滚动的位置,dx,dy为滚动的偏移量, duration为完成滚动的时间 
    mScroller.startScroll(int startX, int startY, int dx, int dy) //使用默认完成时间250ms 
    mScroller.startScroll(int startX, int startY, int dx, int dy, int duration) 
       
    mScroller.computeScrollOffset() //返回值为boolean,true说明滚动尚未完成,false说明滚动已经完成。这是一个很重要的方法,通常放在View.computeScroll()中,用来判断是否滚动是否结束。

    View的computeScroll()方法使用,此方法在绘制View的每一个子view时都被调用 

    2.举例


    实现下拉刷新的效果  
    主要代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    public class CustomView extends RelativeLayout {
     
        private static final String TAG = "CustomView";
     
        private Scroller mScroller;
        private GestureDetector mGestureDetector;
        public boolean flag = true;
        public StateListener stateListener;
        public CustomView(Context context) {
            this(context, null);
        }
         
        public CustomView(Context context, AttributeSet attrs) {
            super(context, attrs);
            setClickable(true);
            setLongClickable(true);
            mScroller = new Scroller(context);
            mGestureDetector = new GestureDetector(context, new CustomGestureListener());
        }
        public interface StateListener
        {
            public void changeText();
            public void recoverText();
        }
        public void setStateListener(StateListener statelistener)
        {
            this.stateListener = statelistener;
        }
        //调用此方法滚动到目标位置
        public void smoothScrollTo(int fx, int fy) {
            int dx = fx - mScroller.getFinalX();
            int dy = fy - mScroller.getFinalY();
            smoothScrollBy(dx, dy);
        }
     
        //调用此方法设置滚动的相对偏移
        public void smoothScrollBy(int dx, int dy) {
     
            //设置mScroller的滚动偏移量
            mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy);
            invalidate();//这里必须调用invalidate()才能保证computeScroll()会被调用,否则不一定会刷新界面,看不到滚动效果
        }
         
        //在绘制View时,会在draw()过程调用该方法。
        @Override
        public void computeScroll() {
         
            //先判断mScroller滚动是否完成
            if (mScroller.computeScrollOffset()) {
             
                //这里调用View的scrollTo()完成实际的滚动
                scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
                 
                //必须调用该方法,否则不一定能看到滚动效果
                postInvalidate();
            }
            super.computeScroll();
        }
         
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_UP :
                Log.i(TAG, "get Sy" + getScrollY());
                System.out.println(getScrollX()+"x--"+getScrollY()+"y");
                smoothScrollTo(0, 0);
                System.out.println("up");
                break;
            default:
                int distance = getScrollY();
                System.out.println("distance"+distance);
                if(distance <= 0)
                {
                    flag = true;
                    if(distance > -200)
                    {
                        stateListener.recoverText();
                    }
                    else if(distance < -200)
                    {
                        stateListener.changeText();
                    }
                    return mGestureDetector.onTouchEvent(event);
                }else
                {
                    flag = false;
                    return false;
                }
            }
            return super.onTouchEvent(event);
        }
         
        class CustomGestureListener implements GestureDetector.OnGestureListener {
     
            @Override
            public boolean onDown(MotionEvent e) {
                // TODO Auto-generated method stub
                return true;
            }
     
            @Override
            public void onShowPress(MotionEvent e) {
                // TODO Auto-generated method stub
                 
            }
     
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                // TODO Auto-generated method stub
                return false;
            }
     
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2,
                    float distanceX, float distanceY) {
                if(flag)
                {int dis = (int)((distanceY-0.5)/4);
                Log.i(TAG, dis + ".");
                smoothScrollBy(0, dis);}
                return false;
            }
     
            @Override
            public void onLongPress(MotionEvent e) {
                // TODO Auto-generated method stub
                 
            }
     
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                    float velocityY) {
                // TODO Auto-generated method stub
                e1.getY();
                e2.getY();
                System.out.println(e1.getY()+"------"+e2.getY());
                return false;
            }
             
        }
    }

    结伴旅游,一个免费的交友网站:www.jieberu.com

    推推族,免费得门票,游景区:www.tuituizu.com

  • 相关阅读:
    第四周学习报告
    第三周学习报告
    第二周学习报告
    第一周学习报告
    大创首月学习计划
    20183122 综合实验《Python程序设计》实验报告
    20183122 实验三《Python程序设计》实验报告
    20183122 实验二《Python程序设计》实验报告
    数据存储和JSON,CSV
    python模块那点事
  • 原文地址:https://www.cnblogs.com/rabbit-bunny/p/4192837.html
Copyright © 2020-2023  润新知