ItemDecoration基于recyclerview中的viewtype

use*_*883 11 java android android-recyclerview

我有多种视图类型,我RecyclerViewItemDecoration根据视图类型添加一个.有没有办法做到这一点?

这将为每个元素添加一个装饰:

recyclerView.addItemDecoration(decoration);
Run Code Online (Sandbox Code Playgroud)

我看过这个库,但它只支持LinearLayoutManager垂直或水平,但我正在使用GrildLayoutManager,我使用drawables分隔.

Dav*_*jak 27

是的你可以.

如果你自己绘制装饰,你可以区分不同的视图类型,getItemOffsetsonDraw通过访问适配器上的相同方法,如下所示:

// get the position
int position = parent.getChildAdapterPosition(view);
// get the view type
int viewType = parent.getAdapter().getItemViewType(position);
Run Code Online (Sandbox Code Playgroud)

使用此选项,您只能为所选视图绘制装饰.通过访问getLeft()getRight()代码支持GridLayout以及LinearLayout支持水平对齐,绘图只需在右侧使用相同的方法完成.

最后,您将创建如下装饰:

public class DividerDecoration extends RecyclerView.ItemDecoration {

    private final Paint mPaint;
    private int mHeightDp;

    public DividerDecoration(Context context) {
        this(context, Color.argb((int) (255 * 0.2), 0, 0, 0), 1f);
    }

    public DividerDecoration(Context context, int color, float heightDp) {
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(color);
        mHeightDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, heightDp, context.getResources().getDisplayMetrics());
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        int position = parent.getChildAdapterPosition(view);
        int viewType = parent.getAdapter().getItemViewType(position);
        if (viewType == MY_VIEW_TYPE) {
            outRect.set(0, 0, 0, mHeightDp);
        } else {
            outRect.setEmpty();
        }
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        for (int i = 0; i < parent.getChildCount(); i++) {
            View view = parent.getChildAt(i);
            int position = parent.getChildAdapterPosition(view);
            int viewType = parent.getAdapter().getItemViewType(position);
            if (viewType == MY_VIEW_TYPE) {
                c.drawRect(view.getLeft(), view.getBottom(), view.getRight(), view.getBottom() + mHeightDp, mPaint);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

GitHub上有一个带有演示项目的类似示例,它不会在标题视图之前或之后绘制,也不会在最后绘制.

  • 您不应该在装饰中访问适配器,适配器的观点可能不是屏幕上的内容(参见 google io talk https://youtu.be/LqBlYJTfLP4?t=2317),将所有必要信息保留在视图持有者中(使用#getChildViewHolder 访问它)。 (4认同)