Java Code Examples for androidx.recyclerview.widget.RecyclerView#getPaddingLeft()

The following examples show how to use androidx.recyclerview.widget.RecyclerView#getPaddingLeft() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: BoxBrowseFragment.java    From box-android-browse-sdk with Apache License 2.0 6 votes vote down vote up
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State 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 top = child.getBottom() + params.bottomMargin;
        int bottom = top + mDivider.getIntrinsicHeight();

        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }
}
 
Example 2
Source File: CustomDividerItemDecoration.java    From Android-skin-support with MIT License 6 votes vote down vote up
@SuppressLint("NewApi")
private void drawVertical(Canvas canvas, RecyclerView parent) {
    canvas.save();
    final int left;
    final int right;
    if (parent.getClipToPadding()) {
        left = parent.getPaddingLeft();
        right = parent.getWidth() - parent.getPaddingRight();
        canvas.clipRect(left, parent.getPaddingTop(), right,
                parent.getHeight() - parent.getPaddingBottom());
    } else {
        left = 0;
        right = parent.getWidth();
    }

    final int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        final View child = parent.getChildAt(i);
        parent.getDecoratedBoundsWithMargins(child, mBounds);
        final int bottom = mBounds.bottom + Math.round(ViewCompat.getTranslationY(child));
        final int top = bottom - mDivider.getIntrinsicHeight();
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(canvas);
    }
    canvas.restore();
}
 
Example 3
Source File: TitleItemDecoration.java    From RvHelper with Apache License 2.0 6 votes vote down vote up
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
    super.onDraw(c, parent, state);

    final int left = parent.getPaddingLeft();
    final int right = parent.getWidth() - parent.getPaddingRight();
    final int childCount = parent.getChildCount();

    for (int i = 0; i < childCount; i++) {
        final View child = parent.getChildAt(i);
        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
        int position = params.getViewLayoutPosition();

        if (position != RecyclerView.NO_POSITION) {

            String currentTag = mDatas.get(position).getTag();
            if (!currentTag.equals(mTopTag) && (position == 0 || !currentTag.equals(mDatas.get(position - 1).getTag()))) {
                //不为空 且跟前一个tag不一样了,说明是新的分类,也要title
                drawTitleArea(c, left, right, child, params, position);
            }
        }
    }
}
 
Example 4
Source File: DividerItem.java    From green_android with GNU General Public License v3.0 6 votes vote down vote up
@Override
public void onDrawOver(final Canvas c, final RecyclerView parent,
                       final RecyclerView.State state) {
    final int left = parent.getPaddingLeft();
    final int right = parent.getWidth() - parent.getPaddingRight();

    final int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; ++i) {
        final View child = parent.getChildAt(i);

        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)child.getLayoutParams();

        final int top = child.getBottom() + params.bottomMargin;
        final int bottom = top + divider.getIntrinsicHeight();

        divider.setBounds(left, top, right, bottom);
        divider.draw(c);
    }
}
 
Example 5
Source File: GridSpacingItemDecoration.java    From MyBookshelf with GNU General Public License v3.0 6 votes vote down vote up
private void drawHorizontal(Canvas canvas, RecyclerView parent) {
    int left = parent.getPaddingLeft();
    int right = parent.getMeasuredWidth() - parent.getPaddingRight();
    final int childSize = parent.getChildCount();
    for (int i = 0; i < childSize; i++) {
        final View child = parent.getChildAt(i);
        RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
        int top = child.getBottom() + layoutParams.bottomMargin;
        int bottom = top + space;
        if (mDivider != null) {
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(canvas);
        }
        if (mPaint != null) {
            canvas.drawRect(left, top, right, bottom, mPaint);
        }

    }
}
 
Example 6
Source File: SimpleDivider.java    From hipda with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State 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 top = child.getBottom() + params.bottomMargin;
        int bottom = top + mDivider.getIntrinsicHeight();

        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }
}
 
Example 7
Source File: HeaderPositionCalculator.java    From toktok-android with GNU General Public License v3.0 5 votes vote down vote up
private boolean isStickyHeaderBeingPushedOffscreen(@NonNull RecyclerView recyclerView, @NonNull View stickyHeader) {
    View viewAfterHeader = getFirstViewUnobscuredByHeader(recyclerView, stickyHeader);
    int firstViewUnderHeaderPosition = recyclerView.getChildAdapterPosition(viewAfterHeader);
    if (firstViewUnderHeaderPosition == RecyclerView.NO_POSITION) {
        return false;
    }

    boolean isReverseLayout = mOrientationProvider.isReverseLayout(recyclerView);
    if (firstViewUnderHeaderPosition > 0 && hasNewHeader(firstViewUnderHeaderPosition, isReverseLayout)) {
        View nextHeader = mHeaderProvider.getHeader(recyclerView, firstViewUnderHeaderPosition);
        mDimensionCalculator.initMargins(mTempRect1, nextHeader);
        mDimensionCalculator.initMargins(mTempRect2, stickyHeader);

        if (mOrientationProvider.getOrientation(recyclerView) == LinearLayoutManager.VERTICAL) {
            int topOfNextHeader = viewAfterHeader.getTop() - mTempRect1.bottom - nextHeader.getHeight() - mTempRect1.top;
            int bottomOfThisHeader = recyclerView.getPaddingTop() + stickyHeader.getBottom() + mTempRect2.top + mTempRect2.bottom;
            if (topOfNextHeader < bottomOfThisHeader) {
                return true;
            }
        } else {
            int leftOfNextHeader = viewAfterHeader.getLeft() - mTempRect1.right - nextHeader.getWidth() - mTempRect1.left;
            int rightOfThisHeader = recyclerView.getPaddingLeft() + stickyHeader.getRight() + mTempRect2.left + mTempRect2.right;
            if (leftOfNextHeader < rightOfThisHeader) {
                return true;
            }
        }
    }

    return false;
}
 
Example 8
Source File: AdvancedDividerItemDecoration.java    From revolution-irc with GNU General Public License v3.0 5 votes vote down vote up
@Override
public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
    canvas.save();
    final int left;
    final int right;
    if (parent.getClipToPadding()) {
        left = parent.getPaddingLeft();
        right = parent.getWidth() - parent.getPaddingRight();
        canvas.clipRect(left, parent.getPaddingTop(), right,
                parent.getHeight() - parent.getPaddingBottom());
    } else {
        left = 0;
        right = parent.getWidth();
    }
    final int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        final View child = parent.getChildAt(i);
        if (!hasDivider(parent, child))
            continue;
        parent.getDecoratedBoundsWithMargins(child, mBounds);
        final int bottom = mBounds.bottom + Math.round(ViewCompat.getTranslationY(child));
        final int top = bottom - mDivider.getIntrinsicHeight();
        mDivider.setBounds(left, top, right, bottom);
        mDivider.setAlpha((int) (child.getAlpha() * 255));
        mDivider.draw(canvas);
    }
    canvas.restore();
}
 
Example 9
Source File: EventItemDecorator.java    From mage-android with Apache License 2.0 5 votes vote down vote up
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
    if (parent.getLayoutManager() == null) {
        return;
    }

    c.save();
    final int left;
    final int right;
    if (parent.getClipToPadding()) {
        left = parent.getPaddingLeft();
        right = parent.getWidth() - parent.getPaddingRight();
        c.clipRect(left, parent.getPaddingTop(), right, parent.getHeight() - parent.getPaddingBottom());
    } else {
        left = 0;
        right = parent.getWidth();
    }

    final int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        final View child = parent.getChildAt(i);
        parent.getDecoratedBoundsWithMargins(child, bounds);

        int position = parent.getChildAdapterPosition(child);
        if (parent.getAdapter().getItemViewType(position) == EventListAdapter.ITEM_TYPE_HEADER ||
            parent.getAdapter().getItemViewType(position + 1) == EventListAdapter.ITEM_TYPE_HEADER ||
            position == state.getItemCount() - 1) {
            continue;
        }

        final int bottom = bounds.bottom + Math.round(ViewCompat.getTranslationY(child));
        final int top = bottom - divider.getIntrinsicHeight();
        divider.setBounds(left, top, right, bottom);
        divider.draw(c);
    }
    c.restore();
}
 
Example 10
Source File: DividerItemDecoration.java    From UltimateRecyclerView with Apache License 2.0 5 votes vote down vote up
public void drawVertical(Canvas c, RecyclerView parent) {
    final int left = parent.getPaddingLeft();
    final int right = parent.getWidth() - parent.getPaddingRight();

    final int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        final View child = parent.getChildAt(i);
        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                .getLayoutParams();
        final int top = child.getBottom() + params.bottomMargin;
        final int bottom = top + mDivider.getIntrinsicHeight();
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }
}
 
Example 11
Source File: DividerItemDecoration.java    From MyBookshelf with GNU General Public License v3.0 5 votes vote down vote up
public void drawVertical(Canvas c, RecyclerView parent) {
    final int left = parent.getPaddingLeft();
    final int right = parent.getWidth() - parent.getPaddingRight();

    final int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        final View child = parent.getChildAt(i);
        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                .getLayoutParams();
        final int top = child.getBottom() + params.bottomMargin;
        final int bottom = top + mDrawable.getIntrinsicHeight();
        mDrawable.setBounds(left, top, right, bottom);
        mDrawable.draw(c);
    }
}
 
Example 12
Source File: InstallerXAdapterDividerItemDecoration.java    From SAI with GNU General Public License v3.0 5 votes vote down vote up
private void drawVertical(Canvas canvas, RecyclerView parent) {
    canvas.save();
    final int left;
    final int right;
    //noinspection AndroidLintNewApi - NewApi lint fails to handle overrides.
    if (parent.getClipToPadding()) {
        left = parent.getPaddingLeft();
        right = parent.getWidth() - parent.getPaddingRight();
        canvas.clipRect(left, parent.getPaddingTop(), right,
                parent.getHeight() - parent.getPaddingBottom());
    } else {
        left = 0;
        right = parent.getWidth();
    }

    final int childCount = parent.getChildCount();
    RecyclerView.Adapter adapter = parent.getAdapter();
    final int itemCount = adapter == null ? -1 : adapter.getItemCount();
    for (int i = 0; i < childCount; i++) {
        final View child = parent.getChildAt(i);
        int adapterPosition = parent.getChildAdapterPosition(child);
        if (adapterPosition == 0 || adapterPosition == itemCount - 1)
            continue;

        parent.getDecoratedBoundsWithMargins(child, mBounds);
        final int bottom = mBounds.bottom + Math.round(child.getTranslationY());
        final int top = bottom - mDivider.getIntrinsicHeight();
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(canvas);
    }
    canvas.restore();
}
 
Example 13
Source File: SpacesItemDecoration.java    From Android-Video-Trimmer with Apache License 2.0 5 votes vote down vote up
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {

  if (parent.getPaddingLeft() != halfSpace) {
    parent.setPadding(halfSpace, halfSpace, halfSpace, halfSpace);
    parent.setClipToPadding(false);
  }

  outRect.top = halfSpace;
  outRect.bottom = halfSpace;
  outRect.left = halfSpace;
  outRect.right = halfSpace;
}
 
Example 14
Source File: GridItemDecoration.java    From BaseRecyclerViewAdapterHelper with MIT License 5 votes vote down vote up
/**
 * @param c
 * @param parent
 * @param state
 */
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
    if (dividerDrawable == null) {
        return;
    }

    int childCount = parent.getChildCount();
    int rightV = parent.getWidth();
    for (int i = 0; i < childCount; i++) {
        View child = parent.getChildAt(i);
        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

        int leftV = parent.getPaddingLeft() + child.getPaddingLeft();
        int bottomV = child.getTop() - params.topMargin;
        int topV = bottomV - dividerDrawable.getIntrinsicHeight();

        int topH = child.getTop() + params.topMargin;
        int bottomH = child.getBottom() + params.bottomMargin;
        int rightH = child.getLeft() - params.leftMargin;
        int leftH = rightH - dividerDrawable.getIntrinsicWidth();
        dividerDrawable.setBounds(leftH, topH, rightH, bottomH);
        dividerDrawable.draw(c);
        dividerDrawable.setBounds(leftV, topV, rightV, bottomV);
        dividerDrawable.draw(c);
    }
}
 
Example 15
Source File: SelectiveDividerItemDecoration.java    From CommonUtils with Apache License 2.0 5 votes vote down vote up
private void drawVertical(Canvas canvas, RecyclerView parent) {
    canvas.save();

    int left;
    int right;
    if (parent.getClipToPadding()) {
        left = parent.getPaddingLeft();
        right = parent.getWidth() - parent.getPaddingRight();
        canvas.clipRect(left, parent.getPaddingTop(), right, parent.getHeight() - parent.getPaddingBottom());
    } else {
        left = 0;
        right = parent.getWidth();
    }

    int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        if (isDecorated(i)) {
            View child = parent.getChildAt(i);
            parent.getDecoratedBoundsWithMargins(child, mBounds);
            int bottom = mBounds.bottom + Math.round(child.getTranslationY());
            int top = bottom - mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(canvas);
        }
    }

    canvas.restore();
}
 
Example 16
Source File: DividerItemDecoration.java    From monero-wallet-android-app with MIT License 5 votes vote down vote up
private void drawVertical(Canvas canvas, RecyclerView parent) {
    canvas.save();
    final int left;
    final int right;
    //noinspection AndroidLintNewApi - NewApi lint fails to handle overrides.
    if (parent.getClipToPadding()) {
        left = parent.getPaddingLeft();
        right = parent.getWidth() - parent.getPaddingRight();
        canvas.clipRect(left, parent.getPaddingTop(), right,
                parent.getHeight() - parent.getPaddingBottom());
    } else {
        left = 0;
        right = parent.getWidth();
    }

    final int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        final View child = parent.getChildAt(i);
        parent.getDecoratedBoundsWithMargins(child, mBounds);
        final int bottom = mBounds.bottom + Math.round(child.getTranslationY());
        final int top = bottom - mDividerSize;
        mDividerPaint.setColor(mDividerColor);
        mDividerPaint.setStyle(Paint.Style.FILL);
        canvas.drawRect(left + mMarginStart, top + mMarginTop, right - mMarginEnd, bottom - mMarginBottom, mDividerPaint);
    }
    canvas.restore();
}
 
Example 17
Source File: WeSwipeHelper.java    From monero-wallet-android-app with MIT License 5 votes vote down vote up
/**
 * Called when {@link #onMove(RecyclerView, RecyclerView.ViewHolder, RecyclerView.ViewHolder)} returns true.
 * <p>
 * WeSwipeHelper does not create an extra Bitmap or View while dragging, instead, it
 * modifies the existing View. Because of this reason, it is important that the View is
 * still part of the layout after it is moved. This may not work as intended when swapped
 * Views are close to RecyclerView bounds or there are gaps between them (e.g. other Views
 * which were not eligible for dropping over).
 * <p>
 * This method is responsible to give necessary hint to the LayoutManager so that it will
 * keep the View in visible area. For example, for LinearLayoutManager, this is as simple
 * as calling {@link LinearLayoutManager#scrollToPositionWithOffset(int, int)}.
 * <p>
 * Default implementation calls {@link RecyclerView#scrollToPosition(int)} if the View's
 * new position is likely to be out of bounds.
 * <p>
 * It is important to ensure the ViewHolder will stay visible as otherwise, it might be
 * removed by the LayoutManager if the move causes the View to go out of bounds. In that
 * case, drag will end prematurely.
 *
 * @param recyclerView The RecyclerView controlled by the WeSwipeHelper.
 * @param viewHolder   The ViewHolder under user's control.
 * @param fromPos      The previous adapter position of the dragged item (before it was
 *                     moved).
 * @param target       The ViewHolder on which the currently active item has been dropped.
 * @param toPos        The new adapter position of the dragged item.
 * @param x            The updated left value of the dragged View after drag translations
 *                     are applied. This value does not include margins added by
 *                     {@link RecyclerView.ItemDecoration}s.
 * @param y            The updated top value of the dragged View after drag translations
 *                     are applied. This value does not include margins added by
 *                     {@link RecyclerView.ItemDecoration}s.
 */
public void onMoved(final RecyclerView recyclerView,
                    final RecyclerView.ViewHolder viewHolder, int fromPos, final RecyclerView.ViewHolder target, int toPos, int x,
                    int y) {
    final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
    if (layoutManager instanceof WeSwipeHelper.ViewDropHandler) {
        ((WeSwipeHelper.ViewDropHandler) layoutManager).prepareForDrop(viewHolder.itemView,
                target.itemView, x, y);
        return;
    }

    // if layout manager cannot handle it, do some guesswork
    if (layoutManager.canScrollHorizontally()) {
        final int minLeft = layoutManager.getDecoratedLeft(target.itemView);
        if (minLeft <= recyclerView.getPaddingLeft()) {
            recyclerView.scrollToPosition(toPos);
        }
        final int maxRight = layoutManager.getDecoratedRight(target.itemView);
        if (maxRight >= recyclerView.getWidth() - recyclerView.getPaddingRight()) {
            recyclerView.scrollToPosition(toPos);
        }
    }

    if (layoutManager.canScrollVertically()) {
        final int minTop = layoutManager.getDecoratedTop(target.itemView);
        if (minTop <= recyclerView.getPaddingTop()) {
            recyclerView.scrollToPosition(toPos);
        }
        final int maxBottom = layoutManager.getDecoratedBottom(target.itemView);
        if (maxBottom >= recyclerView.getHeight() - recyclerView.getPaddingBottom()) {
            recyclerView.scrollToPosition(toPos);
        }
    }
}
 
Example 18
Source File: DividerItemDecoration.java    From RvHelper with Apache License 2.0 5 votes vote down vote up
public void drawVertical(Canvas c, RecyclerView parent) {

        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();

        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }
 
Example 19
Source File: AutoColumnGridLayoutManager.java    From RecyclerExt with Apache License 2.0 4 votes vote down vote up
/**
 * Calculates and adds the amount of spacing that needs to be between each
 * column, row, and the edges of the RecyclerView.  This pays attention to
 * the value from {@link #setSpacingMethod(SpacingMethod)}
 *
 * @param recyclerView The RecyclerView to use for determining the amount of space that needs to be added
 * @param gridItemWidth The requested width for the items
 * @param columnCount The number of columns to display
 */
protected void updateSpacing(@NonNull RecyclerView recyclerView, int gridItemWidth, int columnCount) {
    //Sets the decoration for the calculated spacing
    if (spacerDecoration == null) {
        spacerDecoration = new SpacerDecoration();
        spacerDecoration.setAllowedEdgeSpacing(SpacerDecoration.EDGE_SPACING_LEFT | SpacerDecoration.EDGE_SPACING_RIGHT);
        recyclerView.addItemDecoration(spacerDecoration);
    }

    edgeSpacing = minColumnSpacingEdge;
    int separatorSpacing = minColumnSpacingSeparator / 2;


    //Calculates the edge spacing requirements
    int padding = recyclerView.getPaddingLeft() + recyclerView.getPaddingRight();
    int usableWidth = recyclerView.getWidth() - padding;

    int separatorCount = columnCount -1;
    int spacerCount = 2 * columnCount;

    int freeSpace = usableWidth - (gridItemWidth * columnCount);
    int extraSpace = freeSpace - (2 * minColumnSpacingEdge) - (separatorCount * minColumnSpacingSeparator);

    //If we can add spacing, then we need to calculate how much and where to add it
    if (extraSpace >= spacerCount) {
        if (spacingMethod == SpacingMethod.ALL) {
            int totalMinEdges = minColumnSpacingEdge * 2;
            int totalMinSeparators = separatorCount * minColumnSpacingSeparator;

            //If the totalMinSpace is 0, then the percentage is edge count / separators + edges
            int totalMinSpace = totalMinEdges + totalMinSeparators;
            double edgeSpacePercentage = totalMinSpace == 0 ? (2 / (2 + separatorCount)) : (double)totalMinEdges / (double)totalMinSpace;
            int totalSeparatorSpace = (int)((1d - edgeSpacePercentage) * freeSpace);

            separatorSpacing = spacerCount == 0 ? 0 : totalSeparatorSpace / spacerCount;
            edgeSpacing = ((freeSpace - totalSeparatorSpace) / 2) + separatorSpacing;
        } else if (spacingMethod == SpacingMethod.EDGES) {
            edgeSpacing = (freeSpace - (separatorSpacing * spacerCount)) / 2;
        } else { //SEPARATOR
            separatorSpacing = spacerCount == 0 ? 0 : freeSpace / spacerCount;
        }

        edgeSpacing -= separatorSpacing;
    }

    //Updates the spacing using the decoration and padding
    recyclerView.setPadding(
            recyclerView.getPaddingLeft() + edgeSpacing,
            recyclerView.getPaddingTop(),
            recyclerView.getPaddingRight() + edgeSpacing,
            recyclerView.getPaddingBottom()
    );

    spacerDecoration.update(separatorSpacing, matchSpacing ? separatorSpacing : rowSpacing / 2);
}
 
Example 20
Source File: GroupItemDecoration.java    From CalendarView with Apache License 2.0 4 votes vote down vote up
/**
 * 绘制悬浮组
 *
 * @param c      Canvas
 * @param parent RecyclerView
 */
protected void onDrawOverGroup(Canvas c, RecyclerView parent) {
    int firstVisiblePosition = ((LinearLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
    if (firstVisiblePosition == RecyclerView.NO_POSITION) {
        return;
    }
    Group group = getCroup(firstVisiblePosition);
    if (group == null)
        return;
    String groupTitle = group.toString();
    if (TextUtils.isEmpty(groupTitle)) {
        return;
    }
    boolean isRestore = false;
    Group nextGroup = getCroup(firstVisiblePosition + 1);
    if (nextGroup != null && !group.equals(nextGroup)) {
        //说明是当前组最后一个元素,但不一定碰撞了
        View child = parent.findViewHolderForAdapterPosition(firstVisiblePosition).itemView;
        if (child.getTop() + child.getMeasuredHeight() < mGroupHeight) {
            //进一步检测碰撞
            c.save();//保存画布当前的状态
            isRestore = true;
            c.translate(0, child.getTop() + child.getMeasuredHeight() - mGroupHeight);
        }
    }
    int left = parent.getPaddingLeft();
    int right = parent.getWidth() - parent.getPaddingRight();
    int top = parent.getPaddingTop();
    int bottom = top + mGroupHeight;
    c.drawRect(left, top, right, bottom, mBackgroundPaint);
    float x;
    float y = top + mTextBaseLine;
    if (isCenter) {
        x = parent.getMeasuredWidth() / 2 - getTextX(groupTitle);
    } else {
        x = mPaddingLeft;
    }
    c.drawText(groupTitle, x, y, mTextPaint);
    if (isRestore) {
        //还原画布为初始状态
        c.restore();
    }
}