在实际开发中,我们总是会遇到View滑动的功能,那么可能就会用View的scrollTo(int x, int y)或者scrollBy(int x, int y)方法,但是当你使用这个方法之后,你会发现完全和你想的不是一回事!那么今天,我们就来了解一下,传说中的View的scrollTo(int x, int y)或者scrollBy(int x, int y)方法。如果你对Android 坐标系还不了解,那么请看这篇文章,Android View(一)-View坐标以及方法说明。

一.认识mScrollXmScrollY

    我们需要认识View里面的两个变量,mScrollXmScrollY,看看View是怎么定义的,

/**     * The offset, in pixels, by which the content of this view is scrolled     * horizontally.     * {@hide}     */    @ViewDebug.ExportedProperty(category = "scrolling")    protected int mScrollX;    /**     * The offset, in pixels, by which the content of this view is scrolled     * vertically.     * {@hide}     */    @ViewDebug.ExportedProperty(category = "scrolling")    protected int mScrollY;

获取mScrollX的值,View提供的方法,

/**     * Return the scrolled left position of this view. This is the left edge of     * the displayed part of your view. You do not need to draw any pixels     * farther left, since those are outside of the frame of your view on     * screen.     *     * @return The left edge of the displayed part of your view, in pixels.     */    public final int getScrollX() {        return mScrollX;    }
获取mScrollY的值,View提供的方法,

 /**     * Return the scrolled top position of this view. This is the top edge of     * the displayed part of your view. You do not need to draw any pixels above     * it, since those are outside of the frame of your view on screen.     *     * @return The top edge of the displayed part of your view, in pixels.     */    public final int getScrollY() {        return mScrollY;    }

那么我们需要知道mScrollXmScrollY的变化规律:

(1).mScrollX的值总是等于View左边缘View内容左边缘水平方向距离(mScrollX=X1-X2,,其中X1,表示View的左边缘,其中X2,表示View内容的左边缘),当View内容的左边缘位于View的左边缘的左边时,mScrollX大于零,即mScrollX为正值,反之为负值;

(2).mScrollY的值总是等于View上边缘View内容上边缘竖直方向距离(mScrollY=Y1-Y2,,其中Y1,表示View的上边缘,其中Y2,表示View内容的上边缘),当View内容的上边缘位于View的上边缘的上边时,mScrollY大于零,即mScrollY为正值,反之为负值;

    View边缘是指View的位置,由4个顶点组成,View内容的边缘是指View中的内容的边缘,mScrollXmScrollY的单位为像素,默认情况,mScrollXmScrollY都为零。我们简单理解就是,如果从右向左滑动时,mScyuollX大于零,反之小于零;如果从下往上滑动时,mScrollY大于零,反之小于零;

二.scrollTo(int x, int y) scrollBy(int x, int y)方法。

    PS: 我们需要先了解的是,这两个方法实际改变的是View里面的内容位置,或者说View里面的内容的在移动(滚动),不是View的位置发生变化。你可以写个Demo测试一下,看看具体是什么样!

1.   scrollBy(int x, int y)方法,先看看View源码中这个方法的具体实现,如下,

 /**     * Move the scrolled position of your view. This will cause a call to     * {@link #onScrollChanged(int, int, int, int)} and the view will be     * invalidated.     * @param x the amount of pixels to scroll by horizontally     * @param y the amount of pixels to scroll by vertically     */    public void scrollBy(int x, int y) {        scrollTo(mScrollX + x, mScrollY + y);    }

通过这段源码,可以看出,scrollBy(int x, int y)方法其实也是调用了scrollTo(int x, int y)方法,它是基于当前位置的相对滑动,接着我们就看看scrollTo(int x, int y) 方法。

2.   scrollTo(int x, int y) ,View源码中这个方法的具体实现,如下,

/**     * Set the scrolled position of your view. This will cause a call to     * {@link #onScrollChanged(int, int, int, int)} and the view will be     * invalidated.     * @param x the x position to scroll to     * @param y the y position to scroll to     */    public void scrollTo(int x, int y) {        if (mScrollX != x || mScrollY != y) {            int oldX = mScrollX;            int oldY = mScrollY;            mScrollX = x;            mScrollY = y;            invalidateParentCaches();            onScrollChanged(mScrollX, mScrollY, oldX, oldY);            if (!awakenScrollBars()) {                postInvalidateOnAnimation();            }        }    }

scrollTo(int x, int y) ,则实现了基于参数的绝对滑动。if (mScrollX!= x || mScrollY!= y)x便赋值给mScrollX,y便赋值给mScrollY,所以,x和y不是坐标点,是偏移量。先来一张图,


这张图中,绿色的线框是LinearLayout,它里面的内容有TextView(也就是蓝色线框标识的区域),TextView里面红色的线框标识它里面内容区域。

    通过上面的描述,我们可以了解到,当调用view.scrollTo(100, 0) 的时候,View里面的内容是向左移动的;当调用view.scrollTo(-100, 0) 的时候,View里面的内容是向右移动的;我们还是看几张图,可能会更明显一点,





这几张图,显示了当调用view.scrollTo()方法后的效果,同理view.scrollBy()方法的效果也类似,只是,当你调用view.scrollTo()方法后,View的内容是一步移动到指定的位置,而调用view.scrollBy()方法,每次都在现有的基础上移动一定的偏移量!

    通过以上描述,我们可以知道,使用scrollTo(int x, int y) 和scrollBy(int x, int y),只能将View的内容进行移动,并不能将View的位置进行移动,也就是说,不管怎么滑动,View的位置一直都不会发生变化,一直都是初始位置。

    也许有朋友要问,为何当调用view.scrollTo(100, 0) 时,内容反而是向左边移动呢?在此,就给大家介绍几篇文章来看一下!希望对大家有所帮助!(本人水平有限,有错误的地方,欢迎大家指出)

有关文章:Android学习Scroller(一)——View调用scrollTo()的理解及使用

                    Android scrollTo() scrollBy() Scroller讲解及应用

                   Android View中滚动 scrollTo scrollBy mScrollX mScrollY

      


更多相关文章

  1. Android(安卓)调用系统搜索框
  2. TabActivity实现多页显示效果
  3. Android(安卓)tips(十三)-->Android开发过程中使用Lambda表达式
  4. Android启动流程---App层
  5. okhttp3.x的post请求
  6. 详解Serializable
  7. Android闪屏效果实现方法
  8. Android虚拟导航栏遮挡底部的输入框的解决方法
  9. 用Kotlin实现Android点击事件的方法

随机推荐

  1. MySql索引使用策略分析
  2. mysql 如何动态修改复制过滤器
  3. MySQL ddl语句的使用
  4. MySQL中使用binlog时格式该如何选择
  5. mysql 8.0.22 安装配置图文教程
  6. 解决Navicat Premium 连接 MySQL 8.0 报
  7. MySQL null与not null和null与空值'&
  8. MySQL数据操作-DML语句的使用
  9. 详解 MySQL中count函数的正确使用方法
  10. MySQL 基于时间点的快速恢复方案