这是之前在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"/>
在这种情况下,是否可以定义边距和/或直接添加自定义分隔符视图到列表项的布局中,或者是否有更好的方法来实现我的目标?
简单的方法是为RecyclerView设置背景色,为项目设置不同的背景色。这里有一个例子……
<android.support.v7.widget.RecyclerView
android:background="#ECEFF1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"/>
和TextView项目(它可以是任何东西)与底线“x”dp或px。
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="1dp"
android:background="#FFFFFF"/>
输出……
我认为使用一个简单的分隔器会对你有帮助
为每个项目添加分隔符:
1. 将其添加到可绘制目录line_divider.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="1dp"
android:height="1dp" />
<solid android:color="#999999" />
</shape>
2. 创建SimpleDividerItemDecoration类
我用这个例子来定义这个类:
https://gist.github.com/polbins/e37206fbc444207c0e92
package com.example.myapp;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import com.example.myapp.R;
public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration{
private Drawable mDivider;
public SimpleDividerItemDecoration(Resources resources) {
mDivider = resources.getDrawable(R.drawable.line_divider);
}
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
}
3.在使用RecyclerView的活动或片段中,在onCreateView中添加以下内容:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
RecyclerView myRecyclerView = (RecyclerView) layout.findViewById(R.id.my_recycler_view);
myRecyclerView.addItemDecoration(new SimpleDividerItemDecoration(getResources()));
....
}
4. 添加项目之间的间距
你只需要添加padding属性到你的项目视图
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:padding="4dp"
>
..... item structure
</RelativeLayout>
为了在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()
这是我在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)))
下面是我在Kotlin中如何做的,在项目之间设置一个默认大小为10dp的简单空间:
class SimpleItemDecoration(context: Context, space: Int = 10) : RecyclerView.ItemDecoration() {
private val spaceInDp = ConvertUtil.dpToPx(context, space)
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
outRect.left = spaceInDp
outRect.right = spaceInDp
outRect.bottom = spaceInDp
// Add top margin only for the first item to avoid double space between items
if (parent.getChildAdapterPosition(view) == 0) {
outRect.top = spaceInDp
}
}
}
这是dpToPx方法:
fun dpToPx(context: Context, dp: Int): Int {
return (dp * context.resources.displayMetrics.density).toInt()
}
然后像这样将它添加到RecyclerView中:(感谢@MSpeed)
recyclerView.addItemDecoration(SimpleItemDecoration(context))