参考文章:blog.csdn.net/SS_S1gn/art…
1/ 瀑布流
瀑布流独占一行:在adapter 里面判断:
override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
super.onViewAttachedToWindow(holder)
val index = holder.layoutPosition;
//判断若为banner类型,占满一行 , 我用的是BaseQuickAdapter中的ConcatAdapter 头部就只有一个布局,所以不用判断。如果是多布局的adapter 就需要在这里判断
val lp: ViewGroup.LayoutParams? = holder.itemView.layoutParams;
if (lp != null && lp is StaggeredGridLayoutManager.LayoutParams) {
val p: StaggeredGridLayoutManager.LayoutParams = lp
p.isFullSpan = true;
}
}
瀑布流独占一行后的间距:StaggeredTopMatchDecoration
package com.lib.base.widget;
import android.graphics.Rect;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
public class StaggeredTopMatchDecoration extends RecyclerView.ItemDecoration {
private final int spanCount;
private final int spacing;
private final boolean includeEdge;
public StaggeredTopMatchDecoration(int spanCount, int spacing, boolean includeEdge) {
this.spanCount = spanCount;
this.spacing = spacing;
this.includeEdge = includeEdge;
}
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int position = parent.getChildAdapterPosition(view);
if (position == 0) {
return;
}
StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
int spanIndex = layoutParams.getSpanIndex();
outRect.top = spacing;
if (spanIndex == 0) { // left
outRect.left = spacing;
outRect.right = spacing / 2;
} else {
outRect.right = spacing;
outRect.left = spacing / 2;
}
}
}
2/Grid 网格
Grid 网格独占一行
rv.layoutManager = GridLayoutManager(context, 2, GridLayoutManager.VERTICAL, false).also { manager ->
manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
return if (position == (rv.adapter!!.itemCount -1) || position == 0) {
2
} else {
1
}
}
}
}
rv.addItemDecoration(GridTopMatchDecoration(2, SizeUtils.dp2px(8f), true))
Grid 网格独占一行后的间距:GridTopMatchDecoration
package com.lib.base.widget;
import android.graphics.Rect;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
/**
* https://juejin.cn/post/6844904116859174926
* 描述 : RecyclerView GridLayoutManager 等间距。
* <p>
* 等间距需满足两个条件:
* 1.各个模块的大小相等,即 各列的left+right 值相等;
* 2.各列的间距相等,即 前列的right + 后列的left = 列间距;
* <p>
* 在{@link #getItemOffsets(Rect, View, RecyclerView, RecyclerView.State)} 中针对 outRect 的left 和right 满足这两个条件即可
* <p>
* 作者 : shiguotao
* 版本 : V1
* 创建时间 : 2020/3/19 4:54 PM
*/
/**
* @author Aivan
* @date 2024-01-23
* @dec 第一个item 占满 一行的情况
*/
public class GridTopMatchDecoration extends RecyclerView.ItemDecoration {
private final int spanCount;
private final int spacing;
private final boolean includeEdge;
public GridTopMatchDecoration(int spanCount, int spacing, boolean includeEdge) {
this.spanCount = spanCount;
this.spacing = spacing;
this.includeEdge = includeEdge;
}
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
int position = parent.getChildAdapterPosition(view);
if (position == 0) {
return;
}
int column = (position - 1) % spanCount;
if (includeEdge) {
outRect.left = spacing - column * spacing / spanCount;
outRect.right = (column + 1) * spacing / spanCount;
} else {
outRect.left = column * spacing / spanCount;
outRect.right = spacing - (column + 1) * spacing / spanCount;
}
if (position >= 0) {
outRect.top = spacing;
}
outRect.bottom = spacing;
}
}