我的RecyclerView
中有多个视图类型,我想根据视图类型添加ItemDecoration
。有没有办法做到这一点?
这将为每个元素添加装饰:
recyclerView.addItemDecoration(decoration);
我看到了这个library,但它只支持LinearLayoutManager
垂直或水平,但我使用GrildLayoutManager
并且我使用drawables作为分隔符。
答案 0 :(得分:20)
是的,你可以。
如果您自己绘制装饰,可以通过在适配器上访问相同的方法来区分getItemOffsets
和onDraw
中的不同视图类型:
// get the position
int position = parent.getChildAdapterPosition(view);
// get the view type
int viewType = parent.getAdapter().getItemViewType(position);
使用此功能,您只能为所选视图绘制装饰。通过访问代码支持getLeft()
以及getRight()
的{{1}}和GridLayout
来支持水平对齐,必须完成绘图右侧使用相同的方法。
最后,您将创建如下装饰:
LinearLayout
有一个类似的sample on GitHub带有一个演示项目,它不会在标题视图之前或之后或最后绘制。
答案 1 :(得分:2)
根据@David MedenJak的回答,我为不同的视图类型创建了自己的Item Decorator,因为它在上面的部分绘制装饰器,如果它出现在任何正常的行之后,在一个条件中的答案滞后,
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.ColorRes;
import android.support.annotation.DimenRes;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import java.util.Locale;
import mp.data.modal.MRecyclerListItem;
public class HeaderSimpleDividerDecoration extends RecyclerView.ItemDecoration {
private int dividerHeight;
private Paint dividerPaint;
public HeaderSimpleDividerDecoration(Context context, @DimenRes int divider_height, @ColorRes int color) {
dividerPaint = new Paint();
dividerPaint.setColor(getColor(context, color));
dividerHeight = context.getResources().getDimensionPixelSize(divider_height);
}
private int getColor(Context context, @ColorRes int drawable) {
return ContextCompat.getColor(context, drawable);
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int position = parent.getChildAdapterPosition(view);
if(-1 >= position)
return;
int viewType = parent.getAdapter().getItemViewType(position);
if (MRecyclerListItem.TYPE_NORMAL == viewType) {
// outRect.set(0, 0, 0, mHeightDp);
outRect.bottom = dividerHeight;
} else
outRect.setEmpty();
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
int childCount = parent.getChildCount() -1;
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int top = parent.getPaddingTop();
int bottom = parent.getHeight() - parent.getPaddingBottom();
int itemCount = parent.getAdapter().getItemCount();
for (int i = 0; i < childCount ; i++) {
View view = parent.getChildAt(i);
int position = parent.getChildAdapterPosition(view);
int viewType = parent.getAdapter().getItemViewType(position);
if (MRecyclerListItem.TYPE_NORMAL == viewType) {
int nextItem = position + 1;
if(nextItem < itemCount)
{
int nextViewType = parent.getAdapter().getItemViewType(nextItem);
if(MRecyclerListItem.TYPE_NORMAL != nextViewType)
continue;
}
float topDraw = view.getBottom();
float bottomDraw = view.getBottom() + dividerHeight;
c.drawRect(left, topDraw, right, bottomDraw, dividerPaint);
}
}
}
}
MRecyclerListItem.TYPE_NORMAL是普通行的视图类型(标题除外) 请在以下经理中致电上述内容,
mRecyclerview.addItemDecoration(new HeaderSimpleDividerDecoration(context,
2dp , R.color.view_profile_edit_view));
答案 2 :(得分:0)
嗨!
基于项目视图类型对水平Drawable
使用2个ItemSeparator
分隔符的示例:
override fun getItemOffsets(...) {
parent.adapter?.let { adapter ->
val childAdapterPosition = parent.getChildAdapterPosition(view)
.let { if (it == RecyclerView.NO_POSITION) return else it }
rect.right = when (adapter.getItemViewType(childAdapterPosition)) {
YourAdapter.FIRST_ITEM_ID -> firstSeparator.intrinsicWidth
YourAdapter.SECOND_ITEM_ID -> secondSeparator.intrinsicWidth
else -> 0
}
}
}
override fun onDraw(...) {
parent.adapter?.let { adapter ->
parent.children
.forEach { view ->
val childAdapterPosition = parent.getChildAdapterPosition(view)
.let { if (it == RecyclerView.NO_POSITION) return else it }
when (adapter.getItemViewType(childAdapterPosition)) {
CustomAdapter.FIRST_ITEM_ID -> firstSeparator.draw(...)
CustomAdapter.SECOND_ITEM_ID -> secondSeparator.draw(...)
else -> Unit
}
}
}
}
private fun Drawable.draw(view: View, parent: RecyclerView, canvas: Canvas) = apply {
val left = view.right
val top = parent.paddingTop
val right = left + intrinsicWidth
val bottom = top + intrinsicHeight - parent.paddingBottom
bounds = Rect(left, top, right, bottom)
draw(canvas)
}
有关ItemSeparator
的更多信息,Here是我写来解释如何构建自己的自定义ItemDecoration的文章。
答案 3 :(得分:0)
这里有一个较短的代码,用于为某些视图类型绘制分隔线,可以轻松地将其包含在活动/片段类中:
recyclerView.addItemDecoration(new DividerItemDecoration(this, linearLayoutManager.getOrientation()) {
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
Drawable d = getDrawable();
for (int i = 0; i < parent.getChildCount(); i++) {
View view = parent.getChildAt(i);
int position = parent.getChildAdapterPosition(view);
int viewType = parent.getAdapter().getItemViewType(position);
// Draw divider only for view type 2 (can also put position here to remove for certain positions)
if(viewType == 2) {
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
int top = view.getBottom() + params.bottomMargin;
int bottom = top + d.getIntrinsicHeight();
d.setBounds(0, top, parent.getRight(), bottom);
d.draw(c);
}
}
}
});