这是之前在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"/>
在这种情况下,是否可以定义边距和/或直接添加自定义分隔符视图到列表项的布局中,或者是否有更好的方法来实现我的目标?
这是我在Kotlin中为列显示(网格)所做的
class ItemDecorationColumns(private val space: Int) : ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
val position = parent.getChildLayoutPosition(view)
val manager = parent.layoutManager as GridLayoutManager?
val spanCount = manager?.spanCount ?: 0
if (position < spanCount) {
outRect.top = space
}
if (position % 2 != 0) {
outRect.right = space
}
outRect.left = space
outRect.bottom = space
}
}
使用
rvAlbums.addItemDecoration(ItemDecorationColumns(resources.getDimensionPixelSize(R.dimen.space)))
请注意一下Alex Fu在GitHub上的这个文件:
链接
它是“直接从支持演示中提取”的diveritemdecoration .java示例文件。
在我的项目中导入这个文件后,我能够很好地获得分隔线,并将其作为项目装饰添加到回收器视图。
下面是我的onCreateView在我的片段中包含Recyclerview的样子:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_recycler_view, container, false);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.my_recycler_view);
mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL));
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
return rootView;
}
我确信可以做额外的造型,但这只是一个起点。:)
public class VerticalItemDecoration extends RecyclerView.ItemDecoration {
private boolean verticalOrientation = true;
private int space = 10;
public VerticalItemDecoration(int value, boolean verticalOrientation) {
this.space = value;
this.verticalOrientation = verticalOrientation;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
// Skip first item in the list
if (parent.getChildAdapterPosition(view) != 0) {
if (verticalOrientation) {
outRect.set(space, 0, 0, 0);
} else if (!verticalOrientation) {
outRect.set(0, space, 0, 0);
}
}
}
}
mCompletedShippingRecyclerView.addItemDecoration(new VerticalItemDecoration(20,false));
为了在RecylerView中实现项目之间的间隔,我们可以使用ItemDecorators:
addItemDecoration(object : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State,
) {
super.getItemOffsets(outRect, view, parent, state)
if (parent.getChildAdapterPosition(view) > 0) {
outRect.top = 8.dp // Change this value with anything you want. Remember that you need to convert integers to pixels if you are working with dps :)
}
}
})
对于我粘贴的代码,有几件事需要考虑:
You don't really need to call super.getItemOffsets but I chose to, because I want to extend the behavior defined by the base class. If the library got an update doing more logic behind the scenes, we would miss it.
As an alternative to adding top spacing to the Rect, you could also add bottom spacing, but the logic related to getting the last item of the adapter is more complex, so this might be slightly better.
I used an extension property to convert a simple integer to dps: 8.dp. Something like this might work:
val Int.dp: Int
get() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt()
// Extension function works too, but invoking it would become something like 8.dp()
我觉得需要一个简单的、不使用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,而不是另一个视图高度的百分比。