Android 工作记录:Grid 和 瀑布流 独占一行 和 其间的问题

177 阅读1分钟

参考文章: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;  
    }  
}