美文网首页
Android 滑动探究

Android 滑动探究

作者: 小黑炮 | 来源:发表于2020-08-08 14:57 被阅读0次

        # Android 滑动探究 

        ## 1. Android 坐标系

        Android 都是以左上角作为坐标原点

        ## 2. Android Scroll

        针对Android view 的 滑动,即Scroll , 常见的是View实现滑动主要靠三种方式:

        + srollTo/scrollBy等由系统提供的API

        + 通过位移动画实现View的滑动

        + 为View设置LayoutParams,触发View重新布局

        ### 2.1 scrollTo/scrollBy 方法

        这两个应该是业务中实现滑动最常用的两个函数

        - scrollTo(int x, int y)

        ```

            /**

            * 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();

                    }

                }

            }

        ```

        - scrollBy(int x, int y)

        ```

            /**

            * 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底层也是调用scrollTo,有源码可以判断出,scrolltTo()是实现到(x,y)坐标的绝对滑动,scrollBy()则是相对于当前坐标进行相对滑动,这里要对mScrollX,mScrollY,两个参数的概率有所了解:

        - mScrollX : 

        ```

            * The offset, in pixels, by which the content of this view is scrolled

            * horizontally.

            * Please use {@link View#getScrollX()} and {@link View#setScrollX(int)} instead of

            * accessing these directly.

        ```

        这里翻译过来是指视图滚动的偏移量(px),这里引用开发探索中的概括mScrollX的值恒等于View左边缘和View内容左边缘在水平的距离,还是有点难懂,  **这里View的边缘就是正常理解View的边界,而scroll是不会改变View边界位置,只是改变view的内容位置**  ,并且当View的左边缘在view内容的右边时,可以理解为此时滑动应该是往左方向移动,造成view内容左边界往左侧移动,此时mScrollX的值为正值,所以这里我的理解应该是正负表示方向,数组代表偏移量,内容左偏为正,反之为负。  

        - mScrollY : 

        ```

            /**

            * The offset, in pixels, by which the content of this  

            * view is scrolled

            * vertically.

            **/

        ```

        这里mScrollY同理,表示view上边缘和内容上边缘的距离,内容上偏为正,反之为负。  

        这里注意的是,scrollBy/scrollTo均为无过渡滑动,这里如果需要用户感知,可借助Scroller构造自己的smoothScrollto()方法,而RecycleView内以为我们封装了这套方法,其底层也是Scroller实现。  

        ```

        public void smoothScrollBy(int dx, int dy, int duration, Interpolator interpolator) {

                    if (mInterpolator != interpolator) {

                        mInterpolator = interpolator;

                        mScroller = new OverScroller(getContext(), interpolator);

                    }

                    setScrollState(SCROLL_STATE_SETTLING);

                    mLastFlingX = mLastFlingY = 0;

                    mScroller.startScroll(0, 0, dx, dy, duration);

                    if (Build.VERSION.SDK_INT < 23) {

                        // b/64931938 before API 23, startScroll() does not reset getCurX()/getCurY()

                        // to start values, which causes fillRemainingScrollValues() put in obsolete values

                        // for LayoutManager.onLayoutChildren().

                        mScroller.computeScrollOffset();

                    }

                    postOnAnimation();

                }

        ```

        ## 2.2 借助translate动画实现  

        这里的滑动就不是用户手动触发滑动了

        ## 2.3 设置LayoutParam 触发view重新布局  

        设置layoutParam一般用户动态改变View的属性,怎么滑动起来呢,你可以让marginLeft 借助属性动画(ValueAnimator)累加起来,不就动起来了嘛。

        # 3. RecycleView的滑动  

        未完待更

    相关文章

      网友评论

          本文标题:Android 滑动探究

          本文链接:https://www.haomeiwen.com/subject/codhdktx.html