在列表中需要添加空白的分隔符,原来是直接在item_view中使用了layout_marginBottom来实现,后来发现有问题,就是最后一项也出现了分隔符,看起来怪怪的。
于是搜索了一番,发现可以自定义RecyclerView.ItemDecoration来实现,例如参考了这个
RecyclerView自定义分割线
但经过验证,发现最后一项还是带了自定义的分隔符,
/**
* Retrieve any offsets for the given item. Each field of <code>outRect</code> specifies
* the number of pixels that the item view should be inset by, similar to padding or margin.
* The default implementation sets the bounds of outRect to 0 and returns.
*
* <p>
* If this ItemDecoration does not affect the positioning of item views, it should set
* all four fields of <code>outRect</code> (left, top, right, bottom) to zero
* before returning.
*
* <p>
* If you need to access Adapter for additional data, you can call
* {@link RecyclerView#getChildAdapterPosition(View)} to get the adapter position of the
* View.
*
* @param outRect Rect to receive the output.
* @param view The child view to decorate
* @param parent RecyclerView this ItemDecoration is decorating
* @param state The current state of RecyclerView.
*/
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
@NonNull RecyclerView parent, @NonNull State state) {
getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),
parent);
}
这个方法可以来定义分隔符的大小,
一顿操作之后,实现了如下:
package com.your.pkg;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
/**
* 最后一项不带分割线
* copy from {@link DividerItemDecoration}
*/
public class CustomDecoration extends DividerItemDecoration {
public static final String TAG = "CustomDecoration";
private int mOrientation2;
private boolean mIsLinearLayoutManager = false;
private RecyclerView.LayoutManager mLayoutManager;
public CustomDecoration(Context context, int orientation) {
super(context, orientation);
this.mOrientation2 = orientation;
}
/**
* Sets the orientation for this divider. This should be called if
* {@link RecyclerView.LayoutManager} changes orientation.
*
* @param orientation {@link #HORIZONTAL} or {@link #VERTICAL}
*/
public void setOrientation(int orientation) {
super.setOrientation(orientation);
this.mOrientation2 = orientation;
}
/**
* only support {@link androidx.recyclerview.widget.LinearLayoutManager}
* 其他的执行默认规则
*/
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent,
@NonNull RecyclerView.State state) {
Drawable mDivider = getDrawable();
if (mDivider == null) {
outRect.set(0, 0, 0, 0);
return;
}
if (mOrientation2 == VERTICAL) {
//2021/10/12 仅支持LinearLayoutManager
final int itemPosition = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
final RecyclerView.Adapter adapter = parent.getAdapter();
final RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
int childCount = 0;
if (mLayoutManager != layoutManager) {
mLayoutManager = layoutManager;
mIsLinearLayoutManager = (mLayoutManager instanceof LinearLayoutManager);
}
if (mIsLinearLayoutManager && adapter != null) {
childCount = adapter.getItemCount();
}
//最后一项
final boolean isLastRow = childCount > 0 && (itemPosition == childCount - 1);
if (isLastRow) {
outRect.set(0, 0, 0, 0);
} else {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
}
} else {
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}
}
最小程度地修改源码,避免引进新的bug.
基本可以满足自己的需要了,但是不完美的,因为这次修改只支持LinearLayoutManager 以及 垂直滑动的,其他的暂不支持
网友评论