使用ItemDecorator在RecyclerView中创建分隔符

时间:2014-11-11 11:43:24

标签: java android draw android-recyclerview

我正在尝试使用ItemDecorator将一些分隔符添加到RecyclerView中。这是执行此操作的代码的片段。

//...
public abstract C onInflateViewHolder(Context ctx);

public abstract void onBindViewHolder(C holder, int index);

@Override
public void onDraw(Canvas c, RecyclerView parent) {
    if (mOrientation == VERTICAL_LIST) {
        drawVertical(c, parent);
    } else {
        drawHorizontal(c, parent);
    }
}

public void drawVertical(Canvas c, RecyclerView parent) {
    final int left = parent.getPaddingLeft();
    final int right = parent.getWidth() - parent.getPaddingRight();
    for (int i = 0; i < parent.getChildCount(); i++) {
        C view = onInflateViewHolder(mContext);
        onBindViewHolder(view, i);
        RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT);
        //parent.addView(view.itemView, i, p);
        view.itemView.draw(c);
    }
}
//...

如您所见,我尝试使用parent.addView(view.itemView, i, p);parent.addView(view.itemView, i);,最后view.itemView.draw(c);

这是实施:

mItemDecorator =
                new GenericDecorator<ChatDateSeparatorViewHolder>(getActivity(), GenericDecorator.VERTICAL_LIST) {
                    @Override
                    public ChatDateSeparatorViewHolder onInflateViewHolder(Context ctx) {
                        View v = LayoutInflater.from(ctx).inflate(R.layout.chat_message_separator, null);
                        return new ChatDateSeparatorViewHolder(v);
                    }

                    @Override
                    public void onBindViewHolder(ChatDateSeparatorViewHolder holder, int index) {
                        if (index < mAdapter.getItemCount()-1) {
                            ChatMessage previous = mAdapter.getMessage(index);
                            ChatMessage current = mAdapter.getMessage(index+1);

                            long startTime = previous.getSendDate().getTime();
                            long endTime = current.getSendDate().getTime();
                            long diffTime = endTime - startTime;
                            long diffDays = diffTime / (1000 * 60 * 60 * 24);

                            if (diffDays > 0) {
                                holder.text.setText(Converters.format(current.getSendDate(), getActivity()));
                            } else {
                                holder.root.setVisibility(View.GONE);
                            }
                        } else {
                            holder.root.setVisibility(View.GONE);
                        }

                    }
        };

顺便说一下,C是Recycler.ViewHolder,正如您在实现中所看到的那样。

一切似乎都很好但是在尝试添加视图时崩溃了。当我将addView与LayoutParams ad NullpointerException

一起使用时,我得到的例外是at android.support.v7.widget.RecyclerView$LayoutParams.getViewPosition(RecyclerView.java:6957)

我只需要知道如何在不使用适配器的情况下以编程方式将View添加到RecyclerView

修改

我正在尝试在RecyclerView中添加分隔符,这个分隔符将是我从ViewHolder获得的视图,它已完成所有操作,我唯一需要知道的是如何添加,以编程方式,视图(我从ViewHolder获得)进入RecyclerView

以下是应用程序模型的屏幕截图,因此您将有更好的想法:

enter image description here

说“Hoy”(今天是西班牙语)的一行是其中一个分隔符。

2 个答案:

答案 0 :(得分:1)

您可以使用商品View's代码

来完成此操作

Adapter's onBindViewHolder中,您可以确定这是否是当天的最后一条消息。如果这是当天的最后一条消息,那么您可以拨打holder.itemView.setTag("isLastForDay")

之类的内容

然后在你的装饰者中,在循环通过你的RecyclerView's孩子时,阅读每个孩子的标签。如果标签包含“isLastForDay”,则执行“hoy”绘图逻辑。

答案 1 :(得分:0)

这就是我经常这样做的方式

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
    LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
    recyclerView.setLayoutManager(layoutManager);

    RecycleMarginDecoration recycleMarginDecoration = new RecycleMarginDecoration(this);
    recyclerView.addItemDecoration(recycleMarginDecoration);

添加装饰器类

public class RecycleMarginDecoration extends RecyclerView.ItemDecoration {

private int margin;

public RecycleMarginDecoration(Context context) {
  /* Assign value from xml whatever you want to make as margin*/
    margin = context.getResources().getDimensionPixelSize(R.dimen.padding_four);
}

@Override
public void getItemOffsets(
        Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    outRect.set(margin, margin / 2, margin / 2, 0);
}

}