Android 自定义LayoutManager

这个东西花哨的特别难,简单的特别简单,Github有一堆,

今天具体了解一下,方便以后有需求 ,找到相近的效果,知道在哪里修改一些参数就可以了


首先是自定义一个extends  LayoutManager

public class CustomLayoutManager extends RecyclerView.LayoutManager {


    // 设置布局宽高的 这里让它宽高 包裹内容
    @Override
    public RecyclerView.LayoutParams generateDefaultLayoutParams() {
        return new RecyclerView.LayoutParams(RecyclerView.LayoutParams.WRAP_CONTENT
                , RecyclerView.LayoutParams.WRAP_CONTENT);
    }


    // 这个方法是把具体的View 添加到RecyclerView
    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        super.onLayoutChildren(recycler, state);

        // 定义竖直方向的偏移量
        int offsetY = 0;

        for (int i = 0; i < getItemCount(); i++) {
            View childview = recycler.getViewForPosition(i);
            // 添加进去
            addView(childview);

            // 测量子视图使用标准的测量策略,将母公司的填充回收商看来,任何添加物品装饰和孩子考虑利润
            measureChildWithMargins(childview, 0, 0);

            //   一种 属于RecyclerView 的 测量方式 就像 自定义View的 onMeasure
            int width = getDecoratedMeasuredWidth(childview);
            int height = getDecoratedMeasuredHeight(childview);

            // 对应onLayout 方法
            layoutDecorated(childview, 0, offsetY, width, height + offsetY);

            offsetY += height;
        }

    }

}

这里对应的是 Y轴的操作 所以是竖直方向的

效果

Android 自定义LayoutManager_第1张图片

修改一下其中的Y轴操作 ,让他横着展示

// 这个方法是把具体的View 添加到RecyclerView
    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        super.onLayoutChildren(recycler, state);

        // 定义竖直方向的偏移量
        int offsetX = 0;

        for (int i = 0; i < getItemCount(); i++) {
            View childview = recycler.getViewForPosition(i);
            // 添加进去
            addView(childview);

            // 测量子视图使用标准的测量策略,将母公司的填充回收商看来,任何添加物品装饰和孩子考虑利润
            measureChildWithMargins(childview, 0, 0);

            //   一种 属于RecyclerView 的 测量方式 就像 自定义View的 onMeasure
            int width = getDecoratedMeasuredWidth(childview);
            int height = getDecoratedMeasuredHeight(childview);

            // 对应onLayout 方法
            layoutDecorated(childview, offsetX, 0, width+offsetX, height );

            offsetX += width;
        }

    }

 

效果

Android 自定义LayoutManager_第2张图片


然后是:加上滑动

 @Override
    public boolean canScrollHorizontally() {
        return true;
    }

    @Override
    public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
        offsetChildrenHorizontal(-dx);
        return dx;
    }

这样的写下来是无线滑 可能需要判断是够到头了


判断到头

  @Override
    public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
      
        int travel = dx;

        // 如果滑动到最顶部
        if (mSumDx + dx < 0) {
            travel = -mSumDx;
        }

        mSumDx += travel;

        //平移容器内的View

        offsetChildrenHorizontal(-travel);
        return dx;
    }

判断到底

我们需要先获取所有的 宽度

public class CustomLayoutManager extends RecyclerView.LayoutManager {


    // 设置布局宽高的 这里让它宽高 包裹内容
    @Override
    public RecyclerView.LayoutParams generateDefaultLayoutParams() {
        return new RecyclerView.LayoutParams(RecyclerView.LayoutParams.WRAP_CONTENT
                , RecyclerView.LayoutParams.WRAP_CONTENT);
    }


    // 这个方法是把具体的View 添加到RecyclerView


    private int mTotalWidth;

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        super.onLayoutChildren(recycler, state);

        // 定义竖直方向的偏移量
        int offsetX = 0;

        for (int i = 0; i < getItemCount(); i++) {
            View childview = recycler.getViewForPosition(i);
            // 添加进去
            addView(childview);

            // 测量子视图使用标准的测量策略,将母公司的填充回收商看来,任何添加物品装饰和孩子考虑利润
            measureChildWithMargins(childview, 0, 0);

            //   一种 属于RecyclerView 的 测量方式 就像 自定义View的 onMeasure
            int width = getDecoratedMeasuredWidth(childview);
            int height = getDecoratedMeasuredHeight(childview);

            // 对应onLayout 方法
            layoutDecorated(childview, offsetX, 0, width + offsetX, height);

            offsetX += width;
        }

        // 取一个最大的
        mTotalWidth = Math.max(offsetX, getHorizontalSpace());
    }

    /**
     * 总的高度 减去 左padding  右padding
     *
     * @return
     */
    private int getHorizontalSpace() {
        return getWidth() - getPaddingLeft() - getPaddingRight();
    }

    @Override
    public boolean canScrollHorizontally() {
        return true;
    }

    // 一个中间量
    private int mSumDx = 0;

    @Override
    public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {

        int travel = dx;

        // 如果滑动到最顶部
        if (mSumDx + dx < 0) {
            travel = -mSumDx;
        } else if (mSumDx + dx > mTotalWidth - getHorizontalSpace()) {
            travel = mTotalWidth - getHorizontalSpace() - mSumDx;
        }

        mSumDx += travel;

        //平移容器内的View
        offsetChildrenHorizontal(-travel);

        return dx;
    }


}

效果:

 

Android 自定义LayoutManager_第3张图片


横的最完了 竖着改一改

public class CustomLayoutManager extends RecyclerView.LayoutManager {


    // 设置布局宽高的 这里让它宽高 包裹内容
    @Override
    public RecyclerView.LayoutParams generateDefaultLayoutParams() {
        return new RecyclerView.LayoutParams(RecyclerView.LayoutParams.WRAP_CONTENT
                , RecyclerView.LayoutParams.WRAP_CONTENT);
    }


    // 这个方法是把具体的View 添加到RecyclerView


    private int mTotalHeight;

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        super.onLayoutChildren(recycler, state);

        // 定义竖直方向的偏移量
        int offsetY = 0;

        for (int i = 0; i < getItemCount(); i++) {
            View childview = recycler.getViewForPosition(i);
            // 添加进去
            addView(childview);

            // 测量子视图使用标准的测量策略,将母公司的填充回收商看来,任何添加物品装饰和孩子考虑利润
            measureChildWithMargins(childview, 0, 0);

            //   一种 属于RecyclerView 的 测量方式 就像 自定义View的 onMeasure
            int width = getDecoratedMeasuredWidth(childview);
            int height = getDecoratedMeasuredHeight(childview);

            // 对应onLayout 方法
            layoutDecorated(childview, 0, offsetY, width , height + offsetY);

            offsetY += height;
        }

        // 取一个最大的
        mTotalHeight = Math.max(offsetY, getVerticalSpace());
    }

    /**
     * 总的高度 减去 上padding  下padding
     *
     * @return
     */
    private int getVerticalSpace() {
        return getHeight() - getPaddingTop() - getPaddingBottom();
    }


    // 一个中间量
    private int mSumDy = 0;

    @Override
    public boolean canScrollVertically() {
        return true;
    }

    @Override
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
        int travel = dy;

        // 如果滑动到最顶部
        if (mSumDy + dy < 0) {
            travel = -mSumDy;
        } else if (mSumDy + dy > mTotalHeight - getVerticalSpace()) {
            travel = mTotalHeight - getVerticalSpace() - mSumDy;
        }

        mSumDy += travel;

        //平移容器内的View
        offsetChildrenVertical(-travel);

        return dy;
    }
}

可以以这个为基础进行扩展 先参考一下别人的

比如:

这个效果

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(学习ing)