AutoFillAdjustChildAdapterOption--RecycleViewUtil之动态计算均分控件显示childView

概述

很明显这个篇文章名起得不好…
这篇文章是跟另一篇AdjustCountOption文章相关的,两者有关联,但并不需要一定配合起来.只是建议两篇文章都了解一下会更能理解这个工具类的作用与价值.
实现的功能有点难以用简短的词进行描述.我们直接看图吧


特别的需求

有时我们可能会遇到下面这种需求:

从图中可以很明显分析到这个需求的一些要点:

  • 最后一个头像是更多,并且后面不再有其它头像
  • 所有的头像(包括更多)需要显示在一行内,并且在屏幕内
  • 由于设备的多样,无法保证实际在不同的设备上需要的头像的多少(可以大概预算数量范围,但准确数却无法确定)
  • 头像需要均分显示出来

可能的解决方案

如果我们可以动态地计算均分显示childView的数量,并动态设置需要显示的childView的数量那就OK啦~

关于动态计算均分显示childView就是本篇文章需要说明的.而动态设置item数量(不改变数据源的情况下),则是上述说到的文章AdjustCountOption的内容.

解决方案确定下来了,动态设置item也搞定了,那么下面就是动态计算并均分显示childView了.


关于计算的准备

首先我们要明确计算的一个目的.在这个具体例子中,我们是设置了RecycleView的高度,而宽度明显是填充父控件的.
那么重点在于根据RecycleView的高度来计算当前的宽度可以填充多少个childView.

在这里特别地说明一下相关的一些称呼以方便下面说明.

  • 已设置的高度作为确定边或者说是依赖边(填充childView的数量是依赖于该边确定的)
  • 未设置的宽度作为未确定边

而我们需要做到的一个目标是:根据RecycleView的高度,作为childView的边长(正方形)计算得到当前宽度下可填充的childView个数.


关于计算的流程

确定了计算的最终目的,我们应该确定一下计算的流程.

  • 计算出父控件允许绘制的区域
  • 计算出当前宽度按高度划分时最多可划分出多少部分(假设为n)
  • 计算n部分高度宽的view填充后宽度是否还有剩余
  • (假设有剩余宽度)计算剩余宽度平均分配到每个view的两边作为margin的长
  • 设置childView相关的属性并提交给父控件进行绘制布局

大致上我们需要作的就是上面几个操作了.下面将会根据顺序对每个操作进行更详细地说明.


计算父控件绘制的区域

父控件可绘制的区域就很容易获取了,其实就是父控件的宽高.

//获取父控件的宽
int width=parent.getWidth();
//获取父控件的高
int height=parent.getHeight();

但是,这里需要注意一下.有时父控件的展示子view的绘制区域并不一定是宽高大小.为什么呢?每个view都有的一个属性是padding,当view设置了padding属性后,view可绘制内容的区域就变小了.

而这个属性其实在RecycleView中也并不是很少被使用,所以我们必须注意这一点(当然这个理论对所有的view都是通用的)

//计算父控件实际的可绘制界面大小,除去了padding
public static final Point computeParentViewDrawArea(@NonNull View parentView, @Nullable Point outPoint) {
    if (outPoint == null) {
        outPoint = new Point();
    }
    //计算实际可显示的宽高(去除padding)
    int parentWidth = parentView.getWidth() - parentView.getPaddingLeft() - parentView.getPaddingRight();
    int parentHeight = parentView.getHeight() - parentView.getPaddingTop() - parentView.getPaddingBottom();
    outPoint.set(parentWidth, parentHeight);
    return outPoint;
}

这里没有什么特别的了,返回的Point对象是为了输出结果.


计算未确定边可分割的数量

未确定边(此例中为宽)将以确定边(此例中为高)为边长,计算出当前未确定边最多可分割完整的区域的数量.

对于此例中就是width/height,但是更通用一点可以是这样的.

//基于父控件的宽或者高计算另一边的相对依赖边的可分割数量;
public static final int computeSquareViewCountOnParentView(int parentWidth, int parentHeight,boolean isRelyOnParentWidth) {
    if (parentWidth > 0 && parentHeight > 0) {
        int dividerSize = 0;
        int baseSize = 0;
        //基于宽
        if (isRelyOnParentWidth) {
            baseSize = parentWidth;
            dividerSize = parentHeight;
        } else {
            //基于高
            baseSize = parentHeight;
            dividerSize = parentWidth;
        }
        return dividerSize / baseSize;
    } else {
        return -1;
    }
}

直接给出父控件的宽高并指定依赖边即可计算得到分割数量,这个数量就是childView的个数了.


计算并处理未确定边分割后剩余部分

当未确定边进行分割后,往往并不能恰好分割成整数份的区域,很可能会剩余一部分(宽度),如果childView都挤着放在前面后面空余出来明显是不协调的.
所以我们需要将这部分剩余的长度均分到每一个childView的margin中(注意这里的margin只是额外添加的,并不是指childView真正的margin,childView本身是可以设置margin的,这里计算的部分将是额外添加进去的,并且不会影响childView原本的margin)

计算规则很简单:假设childView有n个,多余的部分长度有s,则应该是这样的:

//这里*2的原因是,将剩余部分均分到每个childView的左右两边作为margin额外添加到最终的布局中
int edgeSize=s/(n*2);

这里计算出来的edgeSize将只会额外添加到childView的左右margin中(针对此例子),不需要管上下margin是因为在此例子中就是将高度作为依赖边进行的计算,一切的操作只是为了未确定边的布局.

如果childView需要上下留白的话,可以直接对childView设置marginTopmarginBottom,当然这样设置会使得childView的宽度大于它的高度(因为宽度跟随父控件高度,而高度现在被设置margin后变小了),所以当需要上下留白时,更好的做法是对整个childView设置margin以保证childView是正方形显示


设置childView的属性

现在已经做好了所有的准备,就需要设置childView的属性并提交给父控件进行布局了.

  • 首先计算childView实际的大小(childView本身可能有margin需求)
//假设父控件实际绘制区域的高度为parentHeight
//计算childView的实际宽长度
int childWidth = parentHeight - childMarginLeft - childMarginRight;
//计算childView的实际高长度
int childHeight = parentHeight - childMarginTop - childMarginBottom;

这里需要注意一下为什么是使用parentHeight减去childView的marginLeftmarginRight.

parentHeight是此次childView的依赖边长(也就是RecycleView的高度),childView的高度已经被确定了,我们需要确定的(就是parentHeight再除去上下的margin部分这么高),所以我们要计算的是实际childView绘制时的宽度,所以这里是使用到了marginLeftmarginRight.

同理childView的高长度也是这么计算,只是减去的margin参数不同而已.


  • 再设置childView的绘制大小与margin
ViewGroup.LayoutParams params = childView.getLayoutParams();
ViewGroup.MarginLayoutParams margin = null;
if (params == null) {
    params = new ViewGroup.LayoutParams(0, 0);
}
//创建margin
margin = new ViewGroup.MarginLayoutParams(params);
//设置子控件的大小
margin.width = childWidth;
margin.height = childHeight;
//设置margin大小
margin.setMargins(childMarginLeft, childMarginTop, childMarginRight, childMarginBottom);

得到childView的宽高后,就可以设置childView的宽高值了.除此之外还有设置chilidView的margin参数.
到这里childView本身的设置就完成了.下面是对刚才计算出来剩余的部分进行的额外margin的添加.

//根据依赖边对多余的空间部分调整添加到margin中
if (isRelyOnParentWidth) {
    //依赖于父控件宽时,添加到上下margin中
    margin.topMargin += edgeSize;
    margin.bottomMargin += edgeSize;
} else {
    //依赖于父控件的高时,添加到左右margin中
    margin.leftMargin += edgeSize;
    margin.rightMargin += edgeSize;
}

最后,再将完全设置好的childView的layout参数重新设置给childView即可.

//设置layout参数
childView.setLayoutParams(margin);

工具类使用方法

上面是分析了整个工具类中对动态计算并均分显示childView的一个计算思想,对应的有相关的操作方法.上述的操作方法声明如下(觉得不好理解太复杂的可以跳过看下面使用方法):

参数有点多,但有4个是margin的参数,不要被吓到了…

/**
 * 计算并设置子view的layoutParams
 *
 * @param childView           子view,可以是直接创建出来的view,可以设置任何的margin/padding等参数,包括view的大小也会重新计算
 * @param childMarginLeft     childView需要的margin-left
 * @param childMarginTop      childView需要的margin-top
 * @param childMarginRight    childView需要的margin-right
 * @param childMarginBottom   childView需要的margin-bottom
 * @param edgeSize            放置childView后父控件剩余的空间进行分配后的边缘的空间部分,可通过方法获取{@link #computeSquareViewEdgeSize(int, int, int, boolean)}
 * @param parentWidth         父控件宽
 * @param parentHeight        父控件高
 * @param isRelyOnParentWidth 是否依赖于父控件的宽
 */
public static final void computeAndSetSquareViewLayoutParams(View childView, int childMarginLeft, int childMarginTop, int childMarginRight, int childMarginBottom, int edgeSize, int parentWidth, int parentHeight, boolean isRelyOnParentWidth) 

/**
 * 计算非依赖边划分的子控件后剩余部分的空间大小用于添加到子控件的margin(宽则添加到left/right,高则添加到top/bottom)部分的大小<br>
 * 如若依赖于宽,则计算规则如下:<br>
 * <pre>
 *     int baseSize = parentWidth;
 *     int layoutSize = baseSize * count;
 *     if (layoutWidth < parentHeight) {
 *     edgeSize = (parentHeight - layoutWidth) / (count * 2);
 *     }
 * </pre>
 * 在例子中的edgeSize就是将添加到childView的marginTop/marginBottom中,用于平均分布到界面上(否则将挤在一起)
 *
 * @param parentWidth         父控件宽
 * @param parentHeight        父控件高
 * @param count               需要显示的子控件
 * @param isRelyOnParentWidth 是否依赖于父控件的宽进行计算
 * @return
 */
public static final int computeSquareViewEdgeSize(int parentWidth, intarentHeight, int count, boolean isRelyOnParentWidth)


/**
 * 基于父控件的宽或者高计算另一边的相对依赖边的可分割数量;如基于宽则返回(width/height),基于高则返回(height/width);
 * 此方法的parentWidth/parentHeight应该已经排除父控件的padding;可通过方法获取{@link #computeParentViewDrawArea(View, Point)}
 *
 * @param isRelyOnParentWidth true为基于宽进行计算,false为基于高进行计算
 * @return 返回值向下取整, 参数不合法返回-1
 */
public static final int computeSquareViewCountOnParentView(int parentWidth, int parentHeight, boolean isRelyOnParentWidth)

使用方法1:全部方法单独调用并处理

该使用方法是灵活性高,有一些可以自己调节.比如当计算出来最多的可设置的childView个数为n时,你将其改为m(n>m)时,通过调用计算edgeSize的方法得到edgeSize并设置view时,完全是OK的,并且也可以很均匀地布局childView(可以参考后面的GIF示例)

//计算父控件实际可绘制区域
Point widthHeightPoint = computeParentViewDrawArea(parentView, widthHeightPoint);
//计算依赖边(边长小的作为依赖边,这个很好理解吧?)
boolean isRelyOnParentWidth = widthHeightPoint.x < widthHeightPoint.y;
//计算未确定边最多可布局的childView数量
int count = computeSquareViewCountOnParentView(widthHeightPoint.x, widthHeightPoint.y, isRelyOnParentWidth);
//计算布局后剩余的分配到每个childView额外的margin长度
int edgeSize = computeSquareViewEdgeSize(widthHeightPoint.x, widthHeightPoint.y, count, isRelyOnParentWidth);

//计算并设置childView的layout参数
RecyclerViewUtil.computeAndSetSquareViewLayoutParams(itemView, 0, 20, 0, 20, edgeSize, widthHeightPoint.x, widthHeightPoint.y, false);

通过以上的操作就可以完成childView的动态计算和测量了.


使用方法2:自动计算

该方法是只需要提供少量的参数,直接调用一个方法就可以计算并返回需要的参数了.最后我们只要设置childView的参数就可以了.
问题的,该方法肯定是以布局childView的最多数量去计算并布局;item的数据是不可控的,只由parentView的大小决定,所以就失去了一定的灵活性.

//创建用于存储父控件绘制宽高大小的参数
Point parentParams = new Point();
//创建用于存储childView布局的数量/额外的marin
Point childParams = new Point();
//一次性自动计算并返回依赖边,true为宽依赖,false为高依赖
boolean relySize = RecyclerViewUtil.computeSquareViewToFixParent(parentView, parentParams, childParams);

//计算并设置childView的layout参数
RecyclerViewUtil.computeAndSetSquareViewLayoutParams(itemView, 0, 0, 0, 0, childParams.y, parentParams.x, parentParams.y, relySize);

方法2看起来赞不赞?这里需要说明一下,传入的两个Point参数必须不为null,因为这两个参数是用来存储计算结果的.方法本身也不允许传入null的参数值.


关于使用的优化问题

最后说一下关于计算的注意事项.

  • 关于复用数据
    对于在一个实际的应用场景,理论上是不会有频繁需要改动布局的情况.所以父控件运行到一个具体的设备第一次加载一个childView时,所有的childView相关的应该是已经计算好了,后面的也childView也可以复用计算的结果.
    所以除了computeAndSetSquareViewLayoutParams()方法在每次绑定或者创建childView时需要使用之外,其它的方法计算得到的结果应该缓存下来在使用此方法时进行复用,不然每创建或者绑定一个childView都去计算一次,想想消耗了很多不必要的资源的.

  • 关于计算的时机
    这时最初的解决目标在于RecycleView上,所以也是考虑了在什么地方使用或者计算更合理和有效.
    我们可以在onBindViewHolder中计算并设置,同时在onCreateViewHolder中也是可以的.但这两个的不同点在哪里呢?
    首先在复用数据(对childView的childCount与edgeSize等的计算结果进行复用)的情况下,都是只计算一次(假设不改动要求),所以这部分没有区别.
    但是由于computeAndSetSquareViewLayoutParams()计算并绑定childView的layout参数是对每一个childView是必须的.所以这个方法必须每次回调都进行操作.
    那么就很容易看出有什么区别了,onBindViewHolder的回调次数必定多于onCreateViewHolder(否则RecycleView就没有什么用了…)

当然本身设置childView的参数并不会有很多的操作,过程也并不麻烦,所以不会消耗很大的一个性能.所以建议:

  • 在仅一次性计算并设置界面时,在onCreateViewHolder()中使用,因为后面不再需要更新界面的布局了.
  • 在需要不断地反复更新界面布局时,则强烈建议在onBindViewHolder()中进行操作了,毕竟本身对性能的影响是很小的.更新界面包括但不限于
1.修改recycleView的大小
2.childView的margin
3.调整childView的item数量

关于不同的使用时机的更新界面方式

我们知道一般更新数据有两种方式.

  • 在需要变更adapter时,通过rv.setAdapter()更新界面(一般数据源也会完全不同)
  • 在不需要变更adapter时,通过adapter.notifyDataSetChanged()更新界面,仅数据源内容改变,数据格式一般不变

当然对于第二种,完全也可以使用rv.setAdapter()的方式进行更新.那么问题就来了.对于不同的更新方式,和我们前面说到的在不同的时机使用计算会有影响么?


onBindViewHolder()中使用

在bindView的过程中使用时,就很明确了.不管你使用使用一种更新方式,只要需要绑定数据显示出来,肯定会调用到onBindViewHolder()方法,所以任何一种更新方式都是支持的.


onCreateViewHolder()中使用

在createView中使用时,情况就会有所不一样了.由于createView只有在需要新的viewHolder时才会被调用,所以存在一个问题.在第一次创建recycleView并显示了数据后,一般viewHolder都被创建了,并且暂时不需要的也被缓存了下来.
当使用adapter.notifyDataSetChanged()时,那么在显示item数量不变的情况下,不会有任何的viewHolder会被创建,则onCreateViewHolder()也肯定不会被调用,所以所有的操作也都不会被执行;

而使用rv.setAadapter()时,所有的缓存的view是会被清除并重新创建的.所以这时onCreateViewHolder()是可以被调用,预期中的逻辑也能正常执行.


更新方式建议

  • 当在bindView中使用时,一般使用adatper.notifyDataSetChanged()更新即可;
  • 当在createView中使用时,一般使用rv.setAdapter()更新即可;

当然重复一下上面的建议:

1.在仅一次性计算并设置界面时,
在`onCreateViewHolder()`中使用,
因为后面不再需要更新界面的布局了.

2.在需要不断地反复更新界面布局时,
则强烈建议在`onBindViewHolder()`中进行操作了,
毕竟本身对性能的影响是很小的.

关于AdjustCountOption相关

前面说了这个跟AdjustCountOption是相关的.如果已经了解过AdjustCountOption的作用,那很明显,AdjustCountOption是用于调整item的数量,而这里是均分并显示childView,当两个组合到一起时,就可以做到不修改使用数据源的情况下实现对RecycleView的平均分割显示(正方形)childView.效果如篇头示例图.

HeaderRecycleAdapter中使用

而前面说了计算的操作最好在onCreateViewHolder中进行,由于HeaderRecycleAdapter(不了解这个adapter的可以查看本系列相关的文章)已经对AdjustCountOption提供了支持,同时又封闭了onCreateViewHolder对外的使用,所以AdjustCountOptioin提供了一个接口用于在每次onCreateViewHolder操作时进行回调.

当然你完全也可以重写这个方法,但HeaderRecycleAdapter创建的初衷就是为了不编写使用的adapter而可以轻松展示各种数据,所以这就违背了设计的初衷,强烈不建议这么做

 /**
  * 每一次当itemView被创建的时候此方法会被回调,建议在这个地方根据parentView进行计算并设置需要调整的itemCount
  *
  * @param itemView
  * @param parentView 此处为RecycleView
  * @param adapter    适配器
  * @param viewType
  */
 public void onCreateViewEverytime(@NonNull View itemView, @NonNull ViewGroup parentView, @NonNull HeaderRecycleAdapter adapter, int viewType);

所以当使用AdjustCountOption时,记得需要计算时在这个方法中进行计算就好了.(当然在setViewHolder中进行计算也行,但是那就跟前面说的一样在onBindViewHolder中操作了).


SimpleRecycleAdapter中使用

最后,SimpleRecycleAdapter(HeaderRecycleAdapter的简单版,用于处理普通的列表数据显示)的内置SimpleAdapterOption已经实现了IAdjustCountOption这个接口,而为了兼容上一版本,所以onCreateViewEverytime方法也已经被空实现了.所以在使用SimpleAdapterOption时需要计算时直接重写onCreateViewEvertytime就可以了.

下面给出一个继承SimpleAdapteOption实现接口的例子.

private class RelyAdapterOption extends SimpleRecycleAdapter.SimpleAdapterOption<String> {
    private Point mParentParams;
    private Point mChildParams;
    private boolean mRelySize;

    public RelyAdapterOption() {
    }

    @Override
    public int getViewType(int position) {
        return 0;
    }

    @Override
    public void setViewHolder(String itemData, int position, HeaderRecycleViewHolder holder) {
        ImageView itemView = (ImageView) holder.getRootView();
        itemView.setImageResource(R.drawable.bg);
        itemView.setScaleType(ImageView.ScaleType.FIT_XY);
    }

    @Override
    public int getLayoutId(int viewType) {
        return R.layout.item_rely;
    }

    @Override
    public void onCreateViewEverytime(@NonNull View itemView, @NonNull ViewGroup parentView, @NonNull HeaderRecycleAdapter adapter, int viewType) {
        //此次确保只计算一次以进行复用
        if(mParentParams == null && mChildParams == null){
            //自动计算并得到依赖数据
            mRelySize =    RecyclerViewUtil.computeSquareViewToFixParent(parentView, mParentParams, mChildParams);
            //设置调整后的item数量
            this.setAdjustCount(mChildParams.x);
        }
        //计算并设置childView的layout参数
        RecyclerViewUtil.computeAndSetSquareViewLayoutParams(itemView, 0, 0, 0, 0, mChildParams.y, mParentParams.x, mParentParams.y, mRelySize);
    }
}

扩展的IAdjustCountOption

本身IAdjustCountOption接口的功能是很简单的,包括调整itemCount的数量也是非常简单不存在什么很难处理的问题.
但是如果配合上自动计算并设置childView的方法,就可能存在很多问题需要处理了.所以这里对这种情况下进行了处理并提供了两个解决方法(其实是相同的,取决于你的使用习惯)

AutoFillAdjustChildAdapterOption

这个adapterOption是由于写测试示例写完后觉得很实用(对有类似需求的人来说),并且发现如果是自己完全去继承IAdjustCountOption去写的话有时逻辑可能还是会有点麻烦,所以特别提供了这个.反正个人感觉是很Awsome了,强烈推荐感受一下.

这是一个抽象类,并继承自于SimpleAdapterOption,所以这个类可以直接进行所有adapter的操作.
关于这个类的方法就不一定列出来了,下面只说它能做到的一些功能,请关注注释.(如果有跟示例GIF中类似的需求的,用这个类就可以轻松完成了)

/**
 * 继承自SimpleAdapterOption,用于自动调整recycleView的item数量及childView的分布显示<br>
 * <li>可实现调整任意的item数量;
 * <li>可实现均等分割界面并规则地显示childView
 * <li>可简单地控制childView的部分布局(margin)
 * <li>可设置是否自动计算(自动计算时item数量将由parentView参数决定,不由用户指定)
 */
public abstract class AdjustCountAdapterOption<T> extends SimpleRecycleAdapter.SimpleAdapterOption<T> {}

这个类实现了依赖于这个工具类的方法,并稍微调整了一下用于适应更多的情况.它的实现是很简单的.下面看看实现的例子.

private class RelyAdapterOption2 extends AdjustCountAdapterOption<String> {
    @Override
    public int getViewType(int position) {
        return 0;
    }

    @Override
    public int getLayoutId(int viewType) {
        return R.layout.item_rely;
    }

    @Override
    public void setViewHolder(String itemData, int position, @NonNull HeaderRecycleViewHolder holder) {
        super.setViewHolder(itemData, position, holder);

        ImageView itemView = (ImageView) holder.getRootView();
        itemView.setImageResource(R.drawable.bg);
        itemView.setScaleType(ImageView.ScaleType.FIT_XY);
    }
}

有没有被惊艳到呢,相比于真的要自己通过方法去计算什么的,这个类封装完了方法让我们更关心于逻辑的实现.看起来就跟直接使用SimpleAdapterOption绑定数据而不进行任何其它操作一样简单~~但他能完成示例中的所有功能.


AutoFillAdjustChildHelper

这个是在上述完成的功能中抽取出来的,独立的helper.完成的功能是与上述的adapterOption的功能是完全一样的.只是不集成在adapterOption中.

可以看一下简单的使用方法,速成集成到adapterOption中.

private class RelyAdapterOption3 extends SimpleRecycleAdapter.SimpleAdapterOption<String> {
    AutoFillAdjustChildHelper mAdjustHelper = null;

    public RelyAdapterOption3() {
        this.mAdjustHelper = new AutoFillAdjustChildHelper();
    }

    //所有与`AutoFillAdjustChildAdapterOption`一样的操作可以从这里进行操作
    public AutoFillAdjustChildHelper getHelper() {
        return mAdjustHelper;
    }

    @Override
    public void onCreateViewEverytime(@NonNull View itemView, @NonNull ViewGroup parentView, @NonNull HeaderRecycleAdapter adapter, int viewType) {
        super.onCreateViewEverytime(itemView, parentView, adapter, viewType);
        //直接调用这个方法,不需要去判断是否需要使用,已经在内部处理了
        mAdjustHelper.computeOnCreateViewHolder(this, itemView, parentView);
    }

    @Override
    public void setViewHolder(String itemData, int position, @NonNull HeaderRecycleViewHolder holder) {
        //相同的直接调用这个方法
        mAdjustHelper.computeOnBindViewHolder(this, holder);
        //自己的绑定逻辑
    }
}

下面把helper中的方法简单介绍一下(跟AutoFillAdjustChildAdapterOption一样,本来并不想写这么多的…).

    /**
     * 设置计算出错的错误通知回调(错误回调接口没有进行测试,但是代码中是确保了出错时会调用,一般来说如果是正常的使用不会有回调事件的)
     */
    public void setOnComputeStatusErrorListener()

    /**
     * 设置当前需要依赖的边长.此方法会决定到实际运行时是否真的会计算出结果;
     */
    public boolean setIsRelyOnWidth()

    /**
     * 统一设置子控件的margin部分
     */
    public void setChildMarginForAll

    /**
     * 获取当前实际可均分显示的itemCount最大数.
     */
    public int getDisplayItemCount() 
    /**
     * 获取parentView被均分显示childView后剩余的空间填充到ChildView之后作为额外margin的长度
     */
    public int getDisplayItemMarginEdgeSize() 

    /**
     * 此方法在界面更新时生效,直接调用不会马上生效,设置后在下一次界面刷新时生效.
     */
    public void requestForceRecompute()

    /**
     * 设置是否进行自动计算
     */
    public void setIsAutoCompute(boolean isAutoCompute)

    /**
     * 设置计算设置childView layoutParams参数的时机
     */
    public void setComputeWhen

    /**
     * 设置希望调整为的item个数,但实际的个数是受到实际的情况影响,如果实际的数据达不到这个数量,会被调整
     *
     * @param adjustCount
     */
    public void setAdjustCount

    /**
     * 在 onCreateViewHolder 中进行计算并设置childView 的参数
     */
    public void computeOnCreateViewHolder

    /**
     * 在 onBindViewHolder 中进行计算并设置bindView 参数
     */
    public void computeOnBindViewHolder

Github地址

https://github.com/CrazyTaro/RecycleViewAdapter
如果觉得有用,欢迎start,可以提供更多动力~谢谢~


示例GIF

图片有点大,需要一点时间下载,请耐心稍等

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值