ItemDecoration实现stickyHeader效果

Posted iblade

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ItemDecoration实现stickyHeader效果相关的知识,希望对你有一定的参考价值。

在这里插入图片描述

/**
 * 快速选择器章节装饰
 */
public class FastIndexSectionDecoration extends RecyclerView.ItemDecoration {

    private Context mContext;
    private List<FilterBean> mData;

    private int backgroundColor;
    private int textColor;
    private float textSize;
    private float textMarginLeft = 35;
    private int mDecorationHeight;

    private Paint mBgPaint;
    private Paint mTextPaint;
    private Rect mTextBounds;

    public FastIndexSectionDecoration(Context context, List<FilterBean> data) {
        this.mContext = context;
        this.mData = data;
        backgroundColor = Color.parseColor("#66C2FFF1");
        textColor = Color.parseColor("#FF9999");
        textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, context.getResources().getDisplayMetrics());

        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setTextSize(textSize);
        mTextPaint.setColor(textColor);

        mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBgPaint.setColor(backgroundColor);

        mDecorationHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 35, context.getResources().getDisplayMetrics());
        mTextBounds = new Rect();
    }


    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);

        if (mData == null || mData.size() == 0) {
            return;
        }

        int position = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewAdapterPosition();
        if (position > mData.size() - 1 || position < 0) {
            return;
        }

        // 第一个分类不需要显示分类章节
        if (position > 0 && !TextUtils.equals(mData.get(position).getFirstChar(), mData.get(position - 1).getFirstChar())) {
            outRect.set(0, mDecorationHeight, 0, 0);
        }
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, 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 position = params.getViewAdapterPosition();
            String indexName = mData.get(position).getFirstChar();
            if (indexName == null) {
                continue;
            }
            if (position > 0 && !TextUtils.equals(indexName, mData.get(position - 1).getFirstChar())) {
                // 背景
                int top = child.getTop() - params.topMargin - mDecorationHeight;
                int bottom = top + mDecorationHeight;
                c.drawRect(left, top, right, bottom, mBgPaint);
                // 文字
                mTextPaint.getTextBounds(indexName, 0, indexName.length(), mTextBounds);
                int h = mTextBounds.height();
                c.drawText(indexName, left + textMarginLeft, bottom - (mDecorationHeight - h) / 2.0f, mTextPaint);
            }
        }
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDrawOver(c, parent, state);

        int firstVisibleItemPosition = ((LinearLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
        // 第一个也不展示decoration
        if (firstVisibleItemPosition <= 0) {
            return;
        }

        boolean hasTrans = false;
        String indexName = mData.get(firstVisibleItemPosition).getFirstChar();
        // 移动decoration
        if (firstVisibleItemPosition + 1 < mData.size()) {
            String nextIndexName = mData.get(firstVisibleItemPosition + 1).getFirstChar();
            if (!TextUtils.equals(indexName, nextIndexName)) {
                View firstVisibleChild = parent.getChildAt(0);
                int transY = firstVisibleChild.getBottom() - (parent.getPaddingTop() + mDecorationHeight);
                if (transY < 0) {
                    c.save();
                    c.translate(0, transY);
                    hasTrans = true;
                }
            }
        }
        float left = parent.getLeft();
        float top = parent.getPaddingTop();
        float right = parent.getWidth() - parent.getPaddingRight();
        float bottom = top + mDecorationHeight;
        // 背景
        c.drawRect(left, top, right, bottom, mBgPaint);
        mTextPaint.getTextBounds(indexName, 0, indexName.length(), mTextBounds);
        //文字
        float baseline = bottom - (mDecorationHeight - mTextBounds.height()) / 2.0f;
        c.drawText(indexName, parent.getPaddingLeft() + textMarginLeft, baseline, mTextPaint);
        if (hasTrans) {
            c.restore();
        }
    }
}

参考文献:https://www.jianshu.com/p/3221b5c8fc38

以上是关于ItemDecoration实现stickyHeader效果的主要内容,如果未能解决你的问题,请参考以下文章

ItemDecoration实现stickyHeader效果

ItemDecoration实现stickyHeader效果

Android 自定义ItemDecoration-实现分组吸顶效果

java DividerItemDecoration。 RecyclerView.ItemDecoration简单实现

使用ItemDecoration给RecyclerView 添加水印

RecyclerView 知识梳理 - ItemDecoration