美文网首页
RecyclerView分组滑动悬停效果

RecyclerView分组滑动悬停效果

作者: GiottoYLY | 来源:发表于2020-12-01 22:11 被阅读0次

    原文:RecyclerView之ItemDecoration由浅入深

    一个RecyclerView使用ItemDecoration实现滑动悬停的效果

    image.png
    public class SectionDecoration extends RecyclerView.ItemDecoration {
    
        private DecorationCallback callback;
        private TextPaint textPaint;
        private Paint paint;
        private int topGap;
        private Paint.FontMetrics fontMetrics;
    
    
        public SectionDecoration(Context context, DecorationCallback callback) {
            this.callback = callback;
    
            paint = new Paint();
            paint.setColor(context.getResources().getColor(R.color.colorAccent));
    
            textPaint = new TextPaint();
            textPaint.setAntiAlias(true);
            textPaint.setColor(Color.BLACK);
            textPaint.setTypeface(Typeface.DEFAULT_BOLD);
            textPaint.setTextSize(80);
            textPaint.getFontMetrics(fontMetrics);
            textPaint.setTextAlign(Paint.Align.LEFT);
            fontMetrics = new Paint.FontMetrics();
    
            topGap = 100;
    
        }
    
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
    
            int index = parent.getChildAdapterPosition(view);
            long groupId = callback.getGroupId(index);
            if (groupId < 0) {
                return;
            }
            if (groupId == 0 || isFirstInGroup(index)) {
                //同组的第一个才添加padding
                outRect.top = topGap;
            } else {
                outRect.top = 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 count = parent.getChildCount();
    //        for (int i = 0; i < count; i++) {
    //            View view = parent.getChildAt(i);
    //            int index = parent.getChildAdapterPosition(view);
    //            long groupId = callback.getGroupId(index);
    //            if (groupId < 0) {
    //                return;
    //            }
    //
    //            String textLine = callback.getGroupFirstLine(index).toUpperCase();
    //            if (index == 0 || isFirstInGroup(index)) {
    //                int top = view.getTop() - topGap;
    //                int bottom = view.getTop();
    //                c.drawRect(left, top, right, bottom, paint);
    //                c.drawText(textLine, left, bottom, textPaint);
    //            }
    //        }
        }
    
        private boolean isFirstInGroup(int pos) {
            if (pos == 0) {
                return true;
            } else {
                long lastGroupId = callback.getGroupId(pos - 1);
                long groupId = callback.getGroupId(pos);
                return lastGroupId != groupId;
            }
        }
    
        @Override
        public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
            super.onDrawOver(c, parent, state);
    
            int itemCount = state.getItemCount();
            int childCount = parent.getChildCount();
            float left = parent.getPaddingLeft();
            float right = parent.getWidth() - parent.getPaddingRight();
            float lineHeight = textPaint.getTextSize() + fontMetrics.descent;
    
            long lastGroupId, groupId = -1;
    
            for (int i = 0; i < childCount; i++) {
                View view = parent.getChildAt(i);
                int position = parent.getChildAdapterPosition(view);
    
                lastGroupId = groupId;
                groupId = callback.getGroupId(position);
    
                if (groupId < 0 || lastGroupId == groupId) {
                    continue;
                }
    
                String textLine = callback.getGroupFirstLine(position).toUpperCase();
                if (TextUtils.isEmpty(textLine)) {
                    continue;
                }
    
                int viewBottom = view.getBottom();
                float textY = Math.max(topGap, view.getTop());
                if (position + 1 < itemCount) {
                    //下一个和当前不一样,移动当前
                    long nextGroupId = callback.getGroupId(position + 1);
                    if (nextGroupId != groupId && viewBottom < textY) {
                        //组内最后一个view进入了header
                        textY = viewBottom;
                    }
                }
    
                c.drawRect(left, textY - topGap, right, textY, paint);
                c.drawText(textLine, left, textY - 15, textPaint);
    
            }
    
        }
    }
    

    调用

       LinearLayoutManager manager = new LinearLayoutManager(this);
            recyclerView.setLayoutManager(manager);
            list = getList();
            adapter = new RecyclerViewAdapter(this, list);
            recyclerView.addItemDecoration(new SectionDecoration(this, new DecorationCallback() {
                @Override
                public long getGroupId(int position) {
                    return Character.toUpperCase(list.get(position).getA().charAt(0));
                }
    
                @Override
                public String getGroupFirstLine(int position) {
                    return list.get(position).getA().substring(0, 1).toUpperCase();
                }
            }));
            recyclerView.setAdapter(adapter);
    

    相关文章

      网友评论

          本文标题:RecyclerView分组滑动悬停效果

          本文链接:https://www.haomeiwen.com/subject/hmaxwktx.html