19.OrientationHelper源码分析-RecyclerView辅助类

简介: OrientationHelperOrientationHelper是对RecycleView中子View管理的辅助类,它是一个抽象类,类中定义了获取View布局信息的相关方法。
OrientationHelper

OrientationHelper是对RecycleView中子View管理的辅助类,它是一个抽象类,类中定义了获取View布局信息的相关方法。虽然是抽象类,但是我们使用中并不需要去继承实现,你会发现createHorizontalHelper和createVerticalHelper两个方法,它是我们今天源码的关键。其实就是在内部new了一个自身的对象,实现了所有的抽象方法,我们直接调用即可。

    /**
     * Creates a horizontal OrientationHelper for the given LayoutManager.
     *
     * @param layoutManager The LayoutManager to attach to.
     * @return A new OrientationHelper
     */
    public static OrientationHelper createHorizontalHelper(
            RecyclerView.LayoutManager layoutManager) {
        return new OrientationHelper(layoutManager) {
            /**
             * Returns the end position of the layout after the end padding is removed.
             * 返回RecycleView内容右边界位置(RecycleView的宽度-paddingRight)
             * @return The end boundary for this layout.
             */
            @Override
            public int getEndAfterPadding() {
                return mLayoutManager.getWidth() - mLayoutManager.getPaddingRight();
            }
            /**
             * Returns the end position of the layout without taking padding into account.
             * 返回的就是RecyclerView的width
             * @return The end boundary for this layout without considering padding.
             */
            @Override
            public int getEnd() {
                return mLayoutManager.getWidth();
            }
            /**
             * Offset all child views attached to the parent RecyclerView by dx pixels along
             * the horizontal axis.
             * 对于Horizontal方向的RecyclerView,这个方法的意思就是在水平方向上移动
             * RecyclerView  单位是px
             * @param dx Pixels to offset by
             */
            @Override
            public void offsetChildren(int amount) {
                mLayoutManager.offsetChildrenHorizontal(amount);
            }
            /**
             * Returns the start position of the layout after the start padding is added.
             * 看源码其实就是return mRecyclerView != null ? mRecyclerView.getPaddingLeft() : 0;
             * 返回的就是RecyclerView的paddingLeft值
             * @return The very first pixel we can draw.
             */
            @Override
            public int getStartAfterPadding() {
                return mLayoutManager.getPaddingLeft();
            }
            /**
             * Returns the space occupied by this View in the current orientation including
             * decorations and margins.
             * 返回view在水平方向上所占位置的大小  view.width+decoration的左右值+leftMargin+rightMargin
             */
            @Override
            public int getDecoratedMeasurement(View view) {
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
                        view.getLayoutParams();
                return mLayoutManager.getDecoratedMeasuredWidth(view) + params.leftMargin
                        + params.rightMargin;
            }
            /**
            * 返回view在竖直方向上所占位置的大小
            * view.height+decoration的top bottom值+topMargin+bottomMargin
            */
            @Override
            public int getDecoratedMeasurementInOther(View view) {
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
                        view.getLayoutParams();
                return mLayoutManager.getDecoratedMeasuredHeight(view) + params.topMargin
                        + params.bottomMargin;
            }
             /**
            * 返回view右边界点的位置
            * view.width+decoration的right值+marginRight,
            * 就是子View右边界点到父View的(0,0)点的水平间距
            */
            @Override
            public int getDecoratedEnd(View view) {
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
                        view.getLayoutParams();
                return mLayoutManager.getDecoratedRight(view) + params.rightMargin;
            }
            /**
            * 返回view左边界点的位置
            * view.width-decoration的left值-marginLeft,
            * 就是子View左边界点到父View的(0,0)点的水平间距
            */
            @Override
            public int getDecoratedStart(View view) {
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
                        view.getLayoutParams();
                return mLayoutManager.getDecoratedLeft(view) - params.leftMargin;
            }
            /**
            * 返回view右侧包含Decoration right值的位置(如果包含decoration的话)
            */
            @Override
            public int getTransformedEndWithDecoration(View view) {
                mLayoutManager.getTransformedBoundingBox(view, true, mTmpRect);
                return mTmpRect.right;
            }
            /**
            * 返回view左侧包含Decoration left值的位置(如果包含decoration的话)
            */
            @Override
            public int getTransformedStartWithDecoration(View view) {
                mLayoutManager.getTransformedBoundingBox(view, true, mTmpRect);
                return mTmpRect.left;
            }
            /**
            * 返回RecyclerView的宽度-paddingLeft-paddingRight的值
            * 刚好是RecyclerView内容区的宽度
            */
            @Override
            public int getTotalSpace() {
                return mLayoutManager.getWidth() - mLayoutManager.getPaddingLeft()
                        - mLayoutManager.getPaddingRight();
            }
            /**
            * 水平方向上移动view,单位是px
            */
            @Override
            public void offsetChild(View view, int offset) {
                view.offsetLeftAndRight(offset);
            }
            /**
            * 返回mRecyclerView.getPaddingRight()
            */
            @Override
            public int getEndPadding() {
                return mLayoutManager.getPaddingRight();
            }
            //返回Recycleview宽度测量模式
            @Override
            public int getMode() {
                return mLayoutManager.getWidthMode();
            }
            //返回Recycleview高度测量模式
            @Override
            public int getModeInOther() {
                return mLayoutManager.getHeightMode();
            }
        };
    }

可以看出,这个类其实就是对LayoutManager的一层封装,用于获取RecyclerView或者其子view的宽高间距等等。另一个方法createVerticalHelper原理和createHorizontalHelper是一样的,可以参考上边的注释进行理解

    /**
     * Creates a vertical OrientationHelper for the given LayoutManager.
     *
     * @param layoutManager The LayoutManager to attach to.
     * @return A new OrientationHelper
     */
    public static OrientationHelper createVerticalHelper(RecyclerView.LayoutManager layoutManager) {
        return new OrientationHelper(layoutManager) {
            @Override
            public int getEndAfterPadding() {
                return mLayoutManager.getHeight() - mLayoutManager.getPaddingBottom();
            }

            @Override
            public int getEnd() {
                return mLayoutManager.getHeight();
            }

            @Override
            public void offsetChildren(int amount) {
                mLayoutManager.offsetChildrenVertical(amount);
            }

            @Override
            public int getStartAfterPadding() {
                return mLayoutManager.getPaddingTop();
            }

            @Override
            public int getDecoratedMeasurement(View view) {
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
                        view.getLayoutParams();
                return mLayoutManager.getDecoratedMeasuredHeight(view) + params.topMargin
                        + params.bottomMargin;
            }

            @Override
            public int getDecoratedMeasurementInOther(View view) {
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
                        view.getLayoutParams();
                return mLayoutManager.getDecoratedMeasuredWidth(view) + params.leftMargin
                        + params.rightMargin;
            }

            @Override
            public int getDecoratedEnd(View view) {
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
                        view.getLayoutParams();
                return mLayoutManager.getDecoratedBottom(view) + params.bottomMargin;
            }

            @Override
            public int getDecoratedStart(View view) {
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
                        view.getLayoutParams();
                return mLayoutManager.getDecoratedTop(view) - params.topMargin;
            }

            @Override
            public int getTransformedEndWithDecoration(View view) {
                mLayoutManager.getTransformedBoundingBox(view, true, mTmpRect);
                return mTmpRect.bottom;
            }

            @Override
            public int getTransformedStartWithDecoration(View view) {
                mLayoutManager.getTransformedBoundingBox(view, true, mTmpRect);
                return mTmpRect.top;
            }

            @Override
            public int getTotalSpace() {
                return mLayoutManager.getHeight() - mLayoutManager.getPaddingTop()
                        - mLayoutManager.getPaddingBottom();
            }

            @Override
            public void offsetChild(View view, int offset) {
                view.offsetTopAndBottom(offset);
            }

            @Override
            public int getEndPadding() {
                return mLayoutManager.getPaddingBottom();
            }

            @Override
            public int getMode() {
                return mLayoutManager.getHeightMode();
            }

            @Override
            public int getModeInOther() {
                return mLayoutManager.getWidthMode();
            }
        };
    }
相关文章
|
3月前
|
存储 Android开发 开发者
Android项目架构设计问题之定义RecyclerView的ViewHolder如何解决
Android项目架构设计问题之定义RecyclerView的ViewHolder如何解决
41 0
构建一个可复用的自定义BaseAdapter
本节给大家带来的是构建一个可复用的自定义BaseAdapter,我们每每涉及到ListView GridView等其他的Adapter控件,都需要自己另外写一个BaseAdapter类,这样显得非常麻烦, 又比如,我们想在一个界面显示两个ListView的话,我们也是需要些两个BaseAdapter。
106 0
|
XML 缓存 算法
重学RecyclerView Adapter封装的深度思考和实现
重学RecyclerView Adapter封装的深度思考和实现
254 0
重学RecyclerView Adapter封装的深度思考和实现
RecyclerView#smoothScrollToPosition调用RecyclerView#OnScrollListener的过程
项目中使用到了RecyclerView#smoothScrollToPosition(0)方法让Recyclerview滚动到顶部,同时给Recyclerview设置了监听器RecyclerView.OnScrollListener。
|
存储 缓存 Kotlin
策略模式应用 | 每当为 RecyclerView 新增类型时就很抓狂
App 界面愈发复杂,元素越来越多,将不同类型的元素组织成 RecyclerView 就可以超越屏幕的限制。常用的RecyclerView在使用时有诸多痛点。这一篇尝试让扩展列表数据类型变得简单。
179 0
|
存储 缓存 算法
读源码长知识 | 更好的 RecyclerView 表项点击监听器
RecyclerView没有提供表项点击事件监听器,只能自己处理。这一篇介绍一种更加解耦,更易于使用的表项点击事件监听方法。
212 0
|
Java 容器
【RecyclerView】二、RecyclerView 简介 ( RecyclerView 特点 | RecyclerView 涉及到的类 )
【RecyclerView】二、RecyclerView 简介 ( RecyclerView 特点 | RecyclerView 涉及到的类 )
187 0
|
缓存 vlayout 前端开发
|
容器 数据格式 XML
View的绘制流程和自定义常用方法的简述
View绘制的方法及过程 1、MyView() 构造方法,这个不做解释,铁定第一个被调用。 作用:传入Context 2、onFinishInflate() 当View中所有的子控件均被映射成xml后触发 3、onMeasure() 在View放置到父...
893 0
|
前端开发 Java Android开发
自定义控件View之onMeasure调用时机源码分析
终于建了一个自己个人小站:https://huangtianyu.gitee.io,以后优先更新小站博客,欢迎进站,O(∩_∩)O~~ 先上测试代码: MainActivity.java import android.
1221 0