Android滑动分析(二)

来源:互联网 发布:水果蔬菜批发软件 编辑:程序博客网 时间:2024/06/07 07:22

1引言:


我们接着上一节滑动分析写,这节通过Scroller类来实现view 跟着手指移动而移动。从而了解Scroller的运行机制。这个类就是一个辅助类,可以在任何view中添加。

2 内容


Scroller类的英文解释:
This class encapsulates scrolling. You can use scrollers (Scroller or OverScroller) to collect the data you need to produce a scrolling animation—for example, in response to a fling gesture. Scrollers track scroll offsets for you over time, but they don’t automatically apply those positions to your view. It’s your responsibility to get and apply new coordinates at a rate that will make the scrolling animation look smooth.
大概意思自己看下。不同就百度翻译。

Scroller类的构造方法有3个:

这里写图片描述

Interpolator 渲染器(插值器)这个相信大家很熟悉,没错就是写animation动画时候反复出现的东西,通过这个Interpolator 可以实现加速,匀速,等效果。

在这里我主要讲几个Scroller常用的几个方法:


public boolean computeScrollOffset (): 当你想知道此view最新的位置时候,你就可以调用这个方法。这个方法返回true 表示动画还没有执行完毕,反之 false 表示动画执行完毕。


getCurrY(): 返回当前y轴的偏移量,什么意思呢,就是指位移的距离


getCurrY(): 返回当前X轴的偏移量。


startScroll(int startX, int startY, int dx, int dy): 执行滑动的方法,startx,startY 值得是,view左上角的x,y坐标,dx,dy表示x轴偏移量,Y轴偏移量


startScroll(int startX, int startY, int dx, int dy,int time): 执行滑动的方法,startx,startY 值得是,view左上角的x,y坐标,dx,dy表示x轴偏移量,Y轴偏移量,time指的是滑动总共耗费的时间。


startScroll(): 这个方法不属于 Scroll类中的方法,它是View/ViewGroup自带的方法,每当view调用ondraw()方法中途会调用这个方法。这个方法是专门留着处理滑动时间的,方法体中没得任何代码。


Scroll类能使view 滑动其中心思想就是,调用view父父布局通过scrollTo 方法来实现滑动。上一节我写过 子view 要想滑动,必须调用父布局的scrollTo方法。意思就是说,父布局调用scrollTo方法,才能是view的位置移动。 因此可以不断调用父布局的scrollTo方法从而可以使,view滑动。 在自定义view里面核心代码就是这些:

 public void startScroll(int x,int y,int dx,int dy,int time)    {        scroller.startScroll(x,y,-dx,-dy,time);        invalidate();    }    @Override    public void computeScroll() {        super.computeScroll();        /*        computeScrollOffset方法判断动画是否执行完毕,true表示没执行完,false表示执行完毕         */        if (scroller.computeScrollOffset())        {            ((View)(this.getParent())).scrollTo(scroller.getCurrX(),scroller.getCurrY());             invalidate();        }    }


startScroll(),方法 view 里面并没有,这是我自己为了写的方便调用scroller.start方法。注意:scroller.startScroll(x,y,-dx,-dy,time);在dx和dy前面我人为加了一个 “-”号,前面已经总结过scrollTo 和scrollby的特点,就是说 为正 往上移,为负往下移。
scroller.startScroll(x,y,-dx,-dy,time);这个方法 就是初始化一些值。打开源码 我们可以查看下。

这里写图片描述

主要就是做初始化操作。


对computeScroll()的重写步骤,首先判断scrolling动作是否执行完毕。然后才能调用父布局的scrollTo方法,不断调整view的位置。

注意:
千万不要忘记了invalidate()方法,invalidate(),重新绘制view,这个地方的作用是想通过invalidate—–>ondraw()—->computeScroll,间接调用 computeScroll ,这样computeScroll方法里面又有一个invalidate又要调用ondraw方法,直到scroller.computeScrollOffset()放回false为止。

下面我们在看下主activity的代码:

MyView view;    RelativeLayout parent;    int x;    int y;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        view=(MyView) findViewById(R.id.myview);        view.setOnTouchListener(this);        parent=(RelativeLayout)view.getParent();    }    @Override    public boolean onTouch(View v, MotionEvent event) {        Toast.makeText(MainActivity.this, "触摸成功", Toast.LENGTH_SHORT).show();        switch (event.getAction())        {            case MotionEvent.ACTION_DOWN:                 x= (int) event.getX();                 y= (int) event.getY();                 break;            case MotionEvent.ACTION_MOVE:                int dx=(int)(event.getX()-x);                int dy=(int)(event.getY()-y);                view.startScroll(parent.getScrollX(),parent.getScrollY(),dx,dy,1);                break;            case MotionEvent.ACTION_UP:                break;        }        return true;    }


在MotionEvent.ACTION_MOVE:过程中,我们可以知道 每次滑动一小段,x,y偏移的距离。因此我们可以把这段小距离当作dx,dy,起始的坐标,就是view的父布局.getgetScrollX()和.getScrollY()。

方法调用顺序是:
view.startScroll()—->scroller.startScroll()—–>view.ondraw()——>view.computeScroll(ondraw中途就会调用此方法)——>ondraw()—->view.computeScroll() 一直这样循环直到结束为止。


经测试:scroller.startScroll()方法 没得time参数的那个startScroll(),会默认加上一个执行scrolling操作的时间,因此我这里设置的非常小,

运行效果如图:
这里写图片描述


总结: scroller这个类 是一个辅助类。可以总结成3步
1.初始化scroller类
2.重写computscroll方法
3.startscroll开启模拟过程

0 0
原创粉丝点击