这是之前在ListView类中使用divider和dividerHeight参数实现的一个例子:
<ListView
android:id="@+id/activity_home_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@android:color/transparent"
android:dividerHeight="8dp"/>
然而,在RecyclerView类中我没有看到这样的可能性。
<android.support.v7.widget.RecyclerView
android:id="@+id/activity_home_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
在这种情况下,是否可以定义边距和/或直接添加自定义分隔符视图到列表项的布局中,或者是否有更好的方法来实现我的目标?
我觉得需要一个简单的、不使用XML的、基于代码的答案
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
ShapeDrawable shapeDrawableForDivider = new ShapeDrawable(new RectShape());
int dividerThickness = // (int) (SomeOtherView.getHeight() * desiredPercent);
shapeDrawableForDivider.setIntrinsicHeight(dividerThickness);
shapeDrawableForDivider.setAlpha(0);
dividerItemDecoration.setDrawable(shapeDrawableForDivider);
recyclerView.addItemDecoration(dividerItemDecoration);
我非常喜欢这个答案,我用Kotlin的单一表达式重新写了一遍:
recyclerView.addItemDecoration(DividerItemDecoration(this,DividerItemDecoration.VERTICAL).also { deco ->
with (ShapeDrawable(RectShape())){
intrinsicHeight = (resources.displayMetrics.density * 24).toInt()
alpha = 0
deco.setDrawable(this)
}
})
这和@Nerdy最初的答案是一样的,只是它将分隔线的高度设置为24dp,而不是另一个视图高度的百分比。
使用RecyclerView itemdecoration -一个基本的分隔符样本在Kotlin android
一个完整的示例,包括一个构建器,添加边缘或使用资源颜色的可能性
class SeparatorDecoration constructor(ctx: Context, @ColorRes dividerColor: Int, heightDp: Float) :
RecyclerView.ItemDecoration() {
private val mPaints = Paint()
init {
mPaints.color = dividerColor
val thickness = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
heightDp,
ctx.resources.displayMetrics
)
mPaints.strokeWidth = thickness
}
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
val params = view.layoutParams as RecyclerView.LayoutParams
// and add a separator to any view but the last one
val p = params.viewAdapterPosition
// and add a separator to any view but the last one
if (p < state.itemCount) outRect[0, 0, 0] =
mPaints.strokeWidth.toInt() // left, top, right, bottom
else outRect.setEmpty() // 0, 0, 0, 0
}
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
// we set the stroke width before, so as to correctly draw the line we have to offset by width / 2
val offset = (mPaints.strokeWidth / 2).roundToInt()
// this will iterate over every visible view
for (i in 0 until parent.childCount) {
// get the view
val view: View = parent.getChildAt(i)
val params = view.layoutParams as RecyclerView.LayoutParams
// get the position
val position = params.viewAdapterPosition
// and finally draw the separator
if (position < state.itemCount) {
c.drawLine(
view.left.toFloat(),
(view.bottom + offset).toFloat(),
view.right.toFloat(), (view.bottom + offset).toFloat(), mPaints
)
}
}
}
}
设置很简单。只需将您的装饰与其余的初始设置一起添加到您的recyclerView。
val decoration = SeparatorDecoration(context, R.color.primaryColor, 1.5f)
recyclerview.addItemDecoration(decoration)
对于那些只在RecyclerView中寻找项目之间的空间的人,请参阅我的方法,在所有项目之间获得相等的空间,除了在第一个和最后一个项目中,我给出了较大的填充。我只应用填充左/右在水平的LayoutManager和顶部/底部在垂直的LayoutManager。
public class PaddingItemDecoration extends RecyclerView.ItemDecoration {
private int mPaddingPx;
private int mPaddingEdgesPx;
public PaddingItemDecoration(Activity activity) {
final Resources resources = activity.getResources();
mPaddingPx = (int) resources.getDimension(R.dimen.paddingItemDecorationDefault);
mPaddingEdgesPx = (int) resources.getDimension(R.dimen.paddingItemDecorationEdge);
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
final int itemPosition = parent.getChildAdapterPosition(view);
if (itemPosition == RecyclerView.NO_POSITION) {
return;
}
int orientation = getOrientation(parent);
final int itemCount = state.getItemCount();
int left = 0;
int top = 0;
int right = 0;
int bottom = 0;
/** Horizontal */
if (orientation == LinearLayoutManager.HORIZONTAL) {
/** All positions */
left = mPaddingPx;
right = mPaddingPx;
/** First position */
if (itemPosition == 0) {
left += mPaddingEdgesPx;
}
/** Last position */
else if (itemCount > 0 && itemPosition == itemCount - 1) {
right += mPaddingEdgesPx;
}
}
/** Vertical */
else {
/** All positions */
top = mPaddingPx;
bottom = mPaddingPx;
/** First position */
if (itemPosition == 0) {
top += mPaddingEdgesPx;
}
/** Last position */
else if (itemCount > 0 && itemPosition == itemCount - 1) {
bottom += mPaddingEdgesPx;
}
}
if (!isReverseLayout(parent)) {
outRect.set(left, top, right, bottom);
} else {
outRect.set(right, bottom, left, top);
}
}
private boolean isReverseLayout(RecyclerView parent) {
if (parent.getLayoutManager() instanceof LinearLayoutManager) {
LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
return layoutManager.getReverseLayout();
} else {
throw new IllegalStateException("PaddingItemDecoration can only be used with a LinearLayoutManager.");
}
}
private int getOrientation(RecyclerView parent) {
if (parent.getLayoutManager() instanceof LinearLayoutManager) {
LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
return layoutManager.getOrientation();
} else {
throw new IllegalStateException("PaddingItemDecoration can only be used with a LinearLayoutManager.");
}
}
}
文件dimens.xml
<resources>
<dimen name="paddingItemDecorationDefault">10dp</dimen>
<dimen name="paddingItemDecorationEdge">20dp</dimen>
</resources>
Here is a simple hack to add a divider
Just add a background to the layout of your recycler item as follows
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_border"
android:gravity="center"
android:orientation="horizontal"
android:padding="5dp">
<ImageView
android:id="@+id/imageViewContactLogo"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginRight="10dp"
android:src="@drawable/ic_user" />
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.92"
android:gravity="center|start"
android:orientation="vertical">
<TextView
android:id="@+id/textViewContactName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/textViewStatusOrNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:singleLine="true"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<TextView
android:id="@+id/textViewUnreadCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:padding="5dp"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/red"
android:textSize="22sp" />
<Button
android:id="@+id/buttonInvite"
android:layout_width="54dp"
android:layout_height="wrap_content"
android:background="@drawable/ic_add_friend" />
</LinearLayout>
在drawable文件夹中创建以下shape_border.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<gradient
android:angle="270"
android:centerColor="@android:color/transparent"
android:centerX="0.01"
android:startColor="#000" />
</shape>
这是最终的结果-一个带分隔符的RecyclerView。
以下是我的偷懒方法,但它很有效:
将CardView包装在一个布局中,并在父布局上设置一个填充/边距来模拟分隔符,并强制将普通分隔符设置为null。
文件list_item.xml
<LinearLayout
android:id="@+id/entry_item_layout_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="<divider_size>" > // This is the divider
<CardView
android:layout_width="<width_size>"
android:layout_height="<height_size>">
...
</CardView>
</LinearLayout
文件list.xml
<RecyclerView
android:divider="@null"
android:layout_width="<width_size>"
android:layout_height="<height_size>"
...
/>