Eye*_*ear 883 android divider android-recyclerview
这是一个如何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"/>
Run Code Online (Sandbox Code Playgroud)
但是,我没有在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"/>
Run Code Online (Sandbox Code Playgroud)
在这种情况下,可以直接定义边距和/或将自定义分隔视图添加到列表项的布局中,还是有更好的方法来实现我的目标?
Eye*_*ear 1159
2016年10月更新
Android支持库版本25.0.0引入了DividerItemDecoration
类:
DividerItemDecoration是一个RecyclerView.ItemDecoration,可用作LinearLayoutManager项目之间的分隔符.它支持HORIZONTAL和VERTICAL方向.
用法:
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
layoutManager.getOrientation());
recyclerView.addItemDecoration(dividerItemDecoration);
Run Code Online (Sandbox Code Playgroud)
以前的答案
有些答案要么使用已被弃用的方法,要么不提供完整的解决方案,所以我尝试做一个简短的最新总结.
与此类不同LinearLayoutManager
,HORIZONTAL
该类没有与分隔符相关的参数.相反,你需要扩展VERTICAL
,一个ListView
内部类:
ItemDecoration允许应用程序从适配器的数据集向特定项视图添加特殊的绘图和布局偏移.这对于在项目,突出显示,可视分组边界等之间绘制分隔符非常有用.
所有ItemDecorations都按照它们添加的顺序绘制,在项目视图之前(在onDraw()中)和项目之后(在onDrawOver(Canvas,RecyclerView,RecyclerView.State)中).
RecyclerView
扩展ItemDecoration
,添加自定义构造函数,将空间高度作为参数并覆盖RecyclerView
方法:
public class VerticalSpaceItemDecoration extends RecyclerView.ItemDecoration {
private final int verticalSpaceHeight;
public VerticalSpaceItemDecoration(int verticalSpaceHeight) {
this.verticalSpaceHeight = verticalSpaceHeight;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
outRect.bottom = verticalSpaceHeight;
}
}
Run Code Online (Sandbox Code Playgroud)
如果您不想在最后一项下面插入空格,请添加以下条件:
if (parent.getChildAdapterPosition(view) != parent.getAdapter().getItemCount() - 1) {
outRect.bottom = verticalSpaceHeight;
}
Run Code Online (Sandbox Code Playgroud)
注意:您还可以修改ItemDecoration
,ItemDecorations
以及onDraw()
对预期效果的性质.
Canvas
扩展RecyclerView
和覆盖RecyclerView.State)
方法:
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
private Drawable divider;
/**
* Default divider will be used
*/
public DividerItemDecoration(Context context) {
final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS);
divider = styledAttributes.getDrawable(0);
styledAttributes.recycle();
}
/**
* Custom divider will be used
*/
public DividerItemDecoration(Context context, int resId) {
divider = ContextCompat.getDrawable(context, resId);
}
@Override
public void onDraw(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 + divider.getIntrinsicHeight();
divider.setBounds(left, top, right, bottom);
divider.draw(c);
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以调用第一个使用默认Android分隔符属性的构造函数,也可以调用第二个使用自己的drawable属性的构造函数,例如drawable/divider.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:height="1dp" />
<solid android:color="#ff992900" />
</shape>
Run Code Online (Sandbox Code Playgroud)
注意:如果你想得出的分隔在您的项目,覆盖Vertical
方法来代替.
若要使用新的类添加ItemDecoration
或ItemDecoration
至height
,例如在片段的getItemOffsets()
方法:
private static final int VERTICAL_ITEM_SPACE = 48;
private RecyclerView recyclerView;
private LinearLayoutManager linearLayoutManager;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_feed, container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_home_recycler_view);
linearLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(linearLayoutManager);
//add ItemDecoration
recyclerView.addItemDecoration(new VerticalSpaceItemDecoration(VERTICAL_ITEM_SPACE));
//or
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));
//or
recyclerView.addItemDecoration(
new DividerItemDecoration(getActivity(), R.drawable.divider));
recyclerView.setAdapter(...);
return rootView;
}
Run Code Online (Sandbox Code Playgroud)
还有Lucas Rocha的图书馆,它应该简化项目装饰过程.虽然没试过.
其功能包括:
Leo*_*der 445
只需添加
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
DividerItemDecoration.VERTICAL));
Run Code Online (Sandbox Code Playgroud)
您还可能需要添加依赖项
compile 'com.android.support:recyclerview-v7:27.1.0'
编辑:
为了自定义它,您可以添加自定义drawable:
DividerItemDecoration itemDecorator = new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL);
itemDecorator.setDrawable(ContextCompat.getDrawable(getContext(), R.drawable.divider));
Run Code Online (Sandbox Code Playgroud)
您可以自由使用任何自定义drawable,例如:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/colorPrimary"/>
<size android:height="0.5dp"/>
</shape>
Run Code Online (Sandbox Code Playgroud)
Duy*_*yen 253
我可能会把你的注意力转移到Alex Fu的Github上的这个特定文件:https: //gist.github.com/alexfu/0f464fc3742f134ccd1e
这是DividerItemDecoration.java示例文件"直接从支持演示中提取".(https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS)
在我的项目中导入此文件后,我能够很好地获得分隔线,并将其作为项目装饰添加到回收器视图中.
以下是我的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_LIST));
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
return rootView;
}
Run Code Online (Sandbox Code Playgroud)
我确信可以做更多的造型,但这是一个起点.:)
Ser*_*eyA 154
简单ItemDecoration
实现所有项目之间的相等空格.
public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
private int space;
public SpacesItemDecoration(int space) {
this.space = space;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.left = space;
outRect.right = space;
outRect.bottom = space;
// Add top margin only for the first item to avoid double space between items
if(parent.getChildAdapterPosition(view) == 0) {
outRect.top = space;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Mad*_*ota 105
简单的一个是为RecyclerView设置背景颜色,为项目设置不同的背景颜色.这是一个例子......
<android.support.v7.widget.RecyclerView
android:background="#ECEFF1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"/>
Run Code Online (Sandbox Code Playgroud)
和TextView项(它可以是任何东西),底边距为"x"dp或px.
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="1dp"
android:background="#FFFFFF"/>
Run Code Online (Sandbox Code Playgroud)
输出 ...
Gen*_*ani 42
我处理 Divider 视图和 Divider Insets 的方式是添加 RecyclerView 扩展。
通过命名 View 或 RecyclerView 添加一个新的扩展文件:
RecyclerViewExtension.kt
Run Code Online (Sandbox Code Playgroud)
并setDivider
在 RecyclerViewExtension.kt 文件中添加扩展方法。
/*
* RecyclerViewExtension.kt
* */
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.RecyclerView
fun RecyclerView.setDivider(@DrawableRes drawableRes: Int) {
val divider = DividerItemDecoration(
this.context,
DividerItemDecoration.VERTICAL
)
val drawable = ContextCompat.getDrawable(
this.context,
drawableRes
)
drawable?.let {
divider.setDrawable(it)
addItemDecoration(divider)
}
}
Run Code Online (Sandbox Code Playgroud)
在drawable
包内创建一个 Drawable 资源文件,如recycler_view_divider.xml
:
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="10dp"
android:insetRight="10dp">
<shape>
<size android:height="0.5dp" />
<solid android:color="@android:color/darker_gray" />
</shape>
</inset>
Run Code Online (Sandbox Code Playgroud)
在这里你可以指定左,右缘上android:insetLeft
和android:insetRight
。
在初始化 RecyclerView 的 Activity 或 Fragment 上,您可以通过调用来设置自定义 drawable:
recyclerView.setDivider(R.drawable.recycler_view_divider)
Run Code Online (Sandbox Code Playgroud)
干杯
Bel*_*lom 41
我认为使用简单的分隔符可以帮助您
为每个项添加分隔符:
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>
Run Code Online (Sandbox Code Playgroud)
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
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()));
....
}
Run Code Online (Sandbox Code Playgroud)
4-要在Items之间添加间距,
只需在项目视图中添加填充属性即可
<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>
Run Code Online (Sandbox Code Playgroud)
Jav*_*tor 36
正如我所说的那样ItemAnimators
.在ItemDecorator
不进入或与动画一起退出.
我只是在每个项目的项目视图布局文件中都有一个视图行.它解决了我的情况.DividerItemDecoration
对于一个简单的分隔者来说,他觉得自己的巫术太多了.
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:background="@color/lt_gray"/>
Run Code Online (Sandbox Code Playgroud)
小智 25
这很简单,你不需要这么复杂的代码
DividerItemDecoration divider = new
DividerItemDecoration(mRVMovieReview.getContext(),
DividerItemDecoration.VERTICAL);
divider.setDrawable(
ContextCompat.getDrawable(getBaseContext(), R.drawable.line_divider)
);
mRVMovieReview.addItemDecoration(divider);
Run Code Online (Sandbox Code Playgroud)
在drawable: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:height="1dp" />
<solid android:color="@android:color/black" />
</shape>
Run Code Online (Sandbox Code Playgroud)
Yoa*_*uet 21
由于没有正确的方法来使用Material Design正确实现这一点,我只是通过以下技巧直接在列表项上添加分隔符:
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/dividerColor"/>
Run Code Online (Sandbox Code Playgroud)
Pra*_*ngh 16
如果有人想要仅添加项目之间的10dp间距,则可以通过将drawable设置为DividerItemDecoration
:
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(
recyclerView.getContext(),
layoutManager.getOrientation()
);
dividerItemDecoration.setDrawable(
ContextCompat.getDrawable(getContext(), R.drawable.divider_10dp)
);
Run Code Online (Sandbox Code Playgroud)
divider_10dp
可绘制资源在哪里包含:
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<size android:height="10dp"/>
<solid android:color="@android:color/transparent"/>
</shape>
Run Code Online (Sandbox Code Playgroud)
fri*_*day 15
使用支持库v25.0.0,最终可以使用基本水平和垂直分隔线的默认实现!
https://developer.android.com/reference/android/support/v7/widget/DividerItemDecoration.html
小智 11
为您的视图添加边距,它对我有用.
android:layout_marginTop="10dp"
Run Code Online (Sandbox Code Playgroud)
如果您只想添加相等的间距并希望以XML格式进行,只需设置padding
为RecyclerView
与layoutMargin
您膨胀的项目相等的数量RecyclerView
,然后让背景颜色确定间距颜色.
Rya*_*ral 11
对于那些谁正在寻找只为项目之间的空间中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.");
}
}
}
Run Code Online (Sandbox Code Playgroud)
dimens.xml
<resources>
<dimen name="paddingItemDecorationDefault">10dp</dimen>
<dimen name="paddingItemDecorationEdge">20dp</dimen>
</resources>
Run Code Online (Sandbox Code Playgroud)
tur*_*oid 11
只需在回收器项目的布局中添加背景,如下所示
<?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>
Run Code Online (Sandbox Code Playgroud)在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>
Run Code Online (Sandbox Code Playgroud)
这是最终结果 - 带分频器的RecyclerView.
Kev*_*ant 10
这实际上并没有解决问题,但作为一种临时解决方法,您可以在XML布局中设置卡上的useCompatPadding属性,使其与Lollipop前版本的测量值相同.
card_view:cardUseCompatPadding="true"
Run Code Online (Sandbox Code Playgroud)
我从旧的gist中分叉了DividerItemDecoration并将其简化为适合我的用例,并且我还修改了它以在ListView中绘制它们的方式绘制分隔符,包括最后一个列表项之后的分隔符.这也将处理垂直ItemAnimator动画:
1)将此类添加到您的项目中:
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
private Drawable divider;
public DividerItemDecoration(Context context) {
try {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
divider = a.getDrawable(0);
a.recycle();
} catch (Resources.NotFoundException e) {
// TODO Log or handle as necessary.
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
if (divider == null) return;
if (parent.getChildAdapterPosition(view) < 1) return;
if (getOrientation(parent) == LinearLayoutManager.VERTICAL)
outRect.top = divider.getIntrinsicHeight();
else
throw new IllegalArgumentException("Only usable with vertical lists");
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (divider == null) {
super.onDrawOver(c, parent, state);
return;
}
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; ++i) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int size = divider.getIntrinsicHeight();
final int top = (int) (child.getTop() - params.topMargin - size + child.getTranslationY());
final int bottom = top + size;
divider.setBounds(left, top, right, bottom);
divider.draw(c);
if (i == childCount - 1) {
final int newTop = (int) (child.getBottom() + params.bottomMargin + child.getTranslationY());
final int newBottom = newTop + size;
divider.setBounds(left, newTop, right, newBottom);
divider.draw(c);
}
}
}
private int getOrientation(RecyclerView parent) {
if (!(parent.getLayoutManager() instanceof LinearLayoutManager))
throw new IllegalStateException("Layout manager must be an instance of LinearLayoutManager");
return ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
}
}
Run Code Online (Sandbox Code Playgroud)
2)将装饰器添加到RecylerView:
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));
Run Code Online (Sandbox Code Playgroud)
而不是创建shape xml
用于更改分隔线高度和颜色的。您可以通过编程方式创建
val divider = DividerItemDecoration(context,
DividerItemDecoration.VERTICAL)
divider.setDrawable(ShapeDrawable().apply {
intrinsicHeight = resources.getDimensionPixelOffset(R.dimen.dp_15)
paint.color = Color.RED // note: currently (support version 28.0.0), we can not use tranparent color here, if we use transparent, we still see a small divider line. So if we want to display transparent space, we can set color = background color or we can create a custom ItemDecoration instead of DividerItemDecoration.
})
recycler_devices.addItemDecoration(divider)
Run Code Online (Sandbox Code Playgroud)
我觉得需要一个不使用 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);
Run Code Online (Sandbox Code Playgroud)
我非常喜欢这个答案,我用单表达式 Kotlin 答案重写了它:
recyclerView.addItemDecoration(DividerItemDecoration(this,DividerItemDecoration.VERTICAL).also { deco ->
with (ShapeDrawable(RectShape())){
intrinsicHeight = (resources.displayMetrics.density * 24).toInt()
alpha = 0
deco.setDrawable(this)
}
})
Run Code Online (Sandbox Code Playgroud)
这与@Nerdy 的原始答案做同样的事情,除了它将分隔线的高度设置为 24dp 而不是另一个视图高度的百分比。
这是一个装饰,可让您设置项目之间的间距以及边缘的间距。这适用于HORIZONTAL
和VERTICAL
布局。
class LinearSpacingDecoration(
@Px private val itemSpacing: Int,
@Px private val edgeSpacing: Int = 0
): RecyclerView.ItemDecoration() {
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
val count = parent.adapter?.itemCount ?: 0
val position = parent.getChildAdapterPosition(view)
val leading = if (position == 0) edgeSpacing else itemSpacing
val trailing = if (position == count - 1) edgeSpacing else 0
outRect.run {
if ((parent.layoutManager as? LinearLayoutManager)?.orientation == LinearLayout.VERTICAL) {
top = leading
bottom = trailing
} else {
left = leading
right = trailing
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
recyclerView.addItemDecoration(LinearSpacingDecoration(itemSpacing = 10, edgeSpacing = 20))
Run Code Online (Sandbox Code Playgroud)
从谷歌搜索中获取,将此ItemDecoration添加到您的RecyclerView
:
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private Drawable mDivider;
private boolean mShowFirstDivider = false;
private boolean mShowLastDivider = false;
public DividerItemDecoration(Context context, AttributeSet attrs) {
final TypedArray a = context
.obtainStyledAttributes(attrs, new int[]{android.R.attr.listDivider});
mDivider = a.getDrawable(0);
a.recycle();
}
public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
boolean showLastDivider) {
this(context, attrs);
mShowFirstDivider = showFirstDivider;
mShowLastDivider = showLastDivider;
}
public DividerItemDecoration(Drawable divider) {
mDivider = divider;
}
public DividerItemDecoration(Drawable divider, boolean showFirstDivider,
boolean showLastDivider) {
this(divider);
mShowFirstDivider = showFirstDivider;
mShowLastDivider = showLastDivider;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
if (mDivider == null) {
return;
}
if (parent.getChildPosition(view) < 1) {
return;
}
if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
outRect.top = mDivider.getIntrinsicHeight();
} else {
outRect.left = mDivider.getIntrinsicWidth();
}
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (mDivider == null) {
super.onDrawOver(c, parent, state);
return;
}
// Initialization needed to avoid compiler warning
int left = 0, right = 0, top = 0, bottom = 0, size;
int orientation = getOrientation(parent);
int childCount = parent.getChildCount();
if (orientation == LinearLayoutManager.VERTICAL) {
size = mDivider.getIntrinsicHeight();
left = parent.getPaddingLeft();
right = parent.getWidth() - parent.getPaddingRight();
} else { //horizontal
size = mDivider.getIntrinsicWidth();
top = parent.getPaddingTop();
bottom = parent.getHeight() - parent.getPaddingBottom();
}
for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
if (orientation == LinearLayoutManager.VERTICAL) {
top = child.getTop() - params.topMargin;
bottom = top + size;
} else { //horizontal
left = child.getLeft() - params.leftMargin;
right = left + size;
}
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
// show last divider
if (mShowLastDivider && childCount > 0) {
View child = parent.getChildAt(childCount - 1);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
if (orientation == LinearLayoutManager.VERTICAL) {
top = child.getBottom() + params.bottomMargin;
bottom = top + size;
} else { // horizontal
left = child.getRight() + params.rightMargin;
right = left + size;
}
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
private int getOrientation(RecyclerView parent) {
if (parent.getLayoutManager() instanceof LinearLayoutManager) {
LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
return layoutManager.getOrientation();
} else {
throw new IllegalStateException(
"DividerItemDecoration can only be used with a LinearLayoutManager.");
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个链接对我来说就像一个魅力:
https://gist.github.com/lapastillaroja/858caf1a82791b6c1a36
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private Drawable mDivider;
private boolean mShowFirstDivider = false;
private boolean mShowLastDivider = false;
public DividerItemDecoration(Context context, AttributeSet attrs) {
final TypedArray a = context
.obtainStyledAttributes(attrs, new int[]{android.R.attr.listDivider});
mDivider = a.getDrawable(0);
a.recycle();
}
public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
boolean showLastDivider) {
this(context, attrs);
mShowFirstDivider = showFirstDivider;
mShowLastDivider = showLastDivider;
}
public DividerItemDecoration(Drawable divider) {
mDivider = divider;
}
public DividerItemDecoration(Drawable divider, boolean showFirstDivider,
boolean showLastDivider) {
this(divider);
mShowFirstDivider = showFirstDivider;
mShowLastDivider = showLastDivider;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
if (mDivider == null) {
return;
}
if (parent.getChildPosition(view) < 1) {
return;
}
if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
outRect.top = mDivider.getIntrinsicHeight();
} else {
outRect.left = mDivider.getIntrinsicWidth();
}
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (mDivider == null) {
super.onDrawOver(c, parent, state);
return;
}
// Initialization needed to avoid compiler warning
int left = 0, right = 0, top = 0, bottom = 0, size;
int orientation = getOrientation(parent);
int childCount = parent.getChildCount();
if (orientation == LinearLayoutManager.VERTICAL) {
size = mDivider.getIntrinsicHeight();
left = parent.getPaddingLeft();
right = parent.getWidth() - parent.getPaddingRight();
} else { //horizontal
size = mDivider.getIntrinsicWidth();
top = parent.getPaddingTop();
bottom = parent.getHeight() - parent.getPaddingBottom();
}
for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
if (orientation == LinearLayoutManager.VERTICAL) {
top = child.getTop() - params.topMargin;
bottom = top + size;
} else { //horizontal
left = child.getLeft() - params.leftMargin;
right = left + size;
}
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
// show last divider
if (mShowLastDivider && childCount > 0) {
View child = parent.getChildAt(childCount - 1);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
if (orientation == LinearLayoutManager.VERTICAL) {
top = child.getBottom() + params.bottomMargin;
bottom = top + size;
} else { // horizontal
left = child.getRight() + params.rightMargin;
right = left + size;
}
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
private int getOrientation(RecyclerView parent) {
if (parent.getLayoutManager() instanceof LinearLayoutManager) {
LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
return layoutManager.getOrientation();
} else {
throw new IllegalStateException(
"DividerItemDecoration can only be used with a LinearLayoutManager.");
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在你的活动中:
mCategoryRecyclerView.addItemDecoration(
new DividerItemDecoration(this, null));
Run Code Online (Sandbox Code Playgroud)
或者如果您使用的是片段:
mCategoryRecyclerView.addItemDecoration(
new DividerItemDecoration(getActivity(), null));
Run Code Online (Sandbox Code Playgroud)
我们可以使用附加到recyclerview的各种装饰器来装饰物品,例如DividerItemDecoration:
只需使用以下内容......取自EyesClear的答案
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
private Drawable mDivider;
/**
* Default divider will be used
*/
public DividerItemDecoration(Context context) {
final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS);
mDivider = styledAttributes.getDrawable(0);
styledAttributes.recycle();
}
/**
* Custom divider will be used
*/
public DividerItemDecoration(Context context, int resId) {
mDivider = ContextCompat.getDrawable(context, resId);
}
@Override
public void onDraw(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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用上面的内容如下
RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST);
recyclerView.addItemDecoration(itemDecoration);
Run Code Online (Sandbox Code Playgroud)
这将在列表中的每个项目之间显示分隔符,如下所示:
对于那些正在寻找更多细节的人,可以查看本指南 使用RecyclerView _ CodePath Android Cliffnotes
这里的一些答案建议使用边距,但问题是:如果你同时添加顶部和底部边距,它们将在项目之间添加,并且它们将太大.如果只添加其中一个,则整个列表的顶部或底部都没有边距.如果在顶部添加一半距离,在底部添加一半,则外边距将太小.
因此,唯一美学上正确的解决方案是系统知道正确应用位置的分隔线:项目之间但不高于或低于项目.
请在下面的评论中告诉我任何疑问:)
如果要为项目添加相同的空间,最简单的方法是为RecycleView
卡片项目添加上边距+左边距和右边距+下边距。
dimens.xml
<resources>
<dimen name="divider">1dp</dimen>
</resources>
Run Code Online (Sandbox Code Playgroud)
list_item.xml
<CardView
android:layout_marginBottom="@dimen/divider"
android:layout_marginRight="@dimen/divider">
...
</CardView>
Run Code Online (Sandbox Code Playgroud)
list.xml
<RecyclerView
...
android:paddingLeft="@dimen/divider"
android:paddingTop="@dimen/divider" />
Run Code Online (Sandbox Code Playgroud)
太晚了,但是GridLayoutManager
我用这个:
public class GridSpacesItemDecoration : RecyclerView.ItemDecoration
{
private int space;
public GridSpacesItemDecoration(int space) {
this.space = space;
}
public override void GetItemOffsets(Android.Graphics.Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
{
var position = parent.GetChildLayoutPosition(view);
/// Only for GridLayoutManager Layouts
var manager = parent.GetLayoutManager() as GridLayoutManager;
if (parent.GetChildLayoutPosition(view) < manager.SpanCount)
outRect.Top = space;
if (position % 2 != 0) {
outRect.Right = space;
}
outRect.Left = space;
outRect.Bottom = space;
}
}
Run Code Online (Sandbox Code Playgroud)
这项工作适用于您拥有的任何跨度计数。
奥莉
您可以通过编程轻松添加。
如果您的布局管理器是Linearlayout,则可以使用:
DividerItemDecoration是RecyclerView.ItemDecoration,可以用作LinearLayoutManager的项目之间的分隔线。它同时支持水平和垂直方向。
mDividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
mLayoutManager.getOrientation());
recyclerView.addItemDecoration(mDividerItemDecoration);
Run Code Online (Sandbox Code Playgroud)
public class CommonItemSpaceDecoration extends RecyclerView.ItemDecoration {
private int mSpace = 0;
private boolean mVerticalOrientation = true;
public CommonItemSpaceDecoration(int space) {
this.mSpace = space;
}
public CommonItemSpaceDecoration(int space, boolean verticalOrientation) {
this.mSpace = space;
this.mVerticalOrientation = verticalOrientation;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.top = SizeUtils.dp2px(view.getContext(), mSpace);
if (mVerticalOrientation) {
if (parent.getChildAdapterPosition(view) == 0) {
outRect.set(0, SizeUtils.dp2px(view.getContext(), mSpace), 0, SizeUtils.dp2px(view.getContext(), mSpace));
} else {
outRect.set(0, 0, 0, SizeUtils.dp2px(view.getContext(), mSpace));
}
} else {
if (parent.getChildAdapterPosition(view) == 0) {
outRect.set(SizeUtils.dp2px(view.getContext(), mSpace), 0, 0, 0);
} else {
outRect.set(SizeUtils.dp2px(view.getContext(), mSpace), 0, SizeUtils.dp2px(view.getContext(), mSpace), 0);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这将在每个项目的顶部和底部(或左侧和右侧)添加空间。然后您可以将其设置为您的recyclerView
.
recyclerView.addItemDecoration(new CommonItemSpaceDecoration(16));
Run Code Online (Sandbox Code Playgroud)
public class SizeUtils {
public static int dp2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
Run Code Online (Sandbox Code Playgroud)
最新的方法是这个,例如在 Fragment 的 onCreateView 中使用:
val recyclerView = rootView.findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.adapter = mListAdapter
recyclerView.layoutManager = LinearLayoutManager(context)
rootView.context.let {
val dividerItemDecoration = MaterialDividerItemDecoration(
it,
MaterialDividerItemDecoration.VERTICAL
)
dividerItemDecoration.isLastItemDecorated = false
// https://github.com/material-components/material-components-android/blob/master/docs/components/Divider.md
// Needed if you did not set colorOnSurface in your theme because otherwise the default color would be pink_900 -> default according to Material should be colorOnSurface (12% opacity applied automatically on top).
// dividerItemDecoration.setDividerColorResource(it, R.color.colorDivider)
recyclerView.addItemDecoration(dividerItemDecoration)
}
Run Code Online (Sandbox Code Playgroud)
我想你可以忘记之前所有其他的解决方案。
归档时间: |
|
查看次数: |
556016 次 |
最近记录: |