com.hippo.widget.recyclerview.LinearDividerItemDecoration.java Source code

Java tutorial

Introduction

Here is the source code for com.hippo.widget.recyclerview.LinearDividerItemDecoration.java

Source

/*
 * Copyright (C) 2015 Hippo Seven
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hippo.widget.recyclerview;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

// Add overlap
/**
 * Only work for {@link android.support.v7.widget.LinearLayoutManager}.<br>
 * Show divider between item, just like
 * {@link android.widget.ListView#setDivider(android.graphics.drawable.Drawable)}
 */
public class LinearDividerItemDecoration extends RecyclerView.ItemDecoration {
    public static final int HORIZONTAL = LinearLayoutManager.HORIZONTAL;
    public static final int VERTICAL = LinearLayoutManager.VERTICAL;

    private boolean mShowFirstDivider = false;
    private boolean mShowLastDivider = false;

    private final Rect mRect;
    private final Paint mPaint;

    private int mOrientation;
    private int mThickness;
    private int mPaddingStart = 0;
    private int mPaddingEnd = 0;

    private boolean mOverlap = false;

    private ShowDividerHelper mShowDividerHelper;

    public LinearDividerItemDecoration(int orientation, int color, int thickness) {
        mRect = new Rect();
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL);
        setOrientation(orientation);
        setColor(color);
        setThickness(thickness);
    }

    public void setShowDividerHelper(ShowDividerHelper showDividerHelper) {
        mShowDividerHelper = showDividerHelper;
    }

    public void setOrientation(int orientation) {
        if (orientation != HORIZONTAL && orientation != VERTICAL) {
            throw new IllegalArgumentException("invalid orientation");
        }
        mOrientation = orientation;
    }

    public void setColor(int color) {
        mPaint.setColor(color);
    }

    public void setThickness(int thickness) {
        mThickness = thickness;
    }

    public void setShowFirstDivider(boolean showFirstDivider) {
        mShowFirstDivider = showFirstDivider;
    }

    public void setShowLastDivider(boolean showLastDivider) {
        mShowLastDivider = showLastDivider;
    }

    public void setPadding(int padding) {
        setPaddingStart(padding);
        setPaddingEnd(padding);
    }

    public void setPaddingStart(int paddingStart) {
        mPaddingStart = paddingStart;
    }

    public void setPaddingEnd(int paddingEnd) {
        mPaddingEnd = paddingEnd;
    }

    public void setOverlap(boolean overlap) {
        mOverlap = overlap;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if (parent.getAdapter() == null) {
            outRect.set(0, 0, 0, 0);
            return;
        }

        if (mOverlap) {
            outRect.set(0, 0, 0, 0);
            return;
        }

        final int position = parent.getChildLayoutPosition(view);
        final int itemCount = parent.getAdapter().getItemCount();

        if (mShowDividerHelper != null) {
            if (mOrientation == VERTICAL) {
                if (position == 0 && mShowDividerHelper.showDivider(0)) {
                    outRect.top = mThickness;
                }
                if (mShowDividerHelper.showDivider(position + 1)) {
                    outRect.bottom = mThickness;
                }
            } else {
                if (position == 0 && mShowDividerHelper.showDivider(0)) {
                    outRect.left = mThickness;
                }
                if (mShowDividerHelper.showDivider(position + 1)) {
                    outRect.right = mThickness;
                }
            }
        } else {
            if (mOrientation == VERTICAL) {
                if (position == 0 && mShowFirstDivider) {
                    outRect.top = mThickness;
                }
                outRect.bottom = mThickness;
                if (position == itemCount - 1 && !mShowLastDivider) {
                    outRect.bottom = 0;
                }
            } else {
                if (position == 0 && mShowFirstDivider) {
                    outRect.left = mThickness;
                }
                outRect.right = mThickness;
                if (position == itemCount - 1 && !mShowLastDivider) {
                    outRect.right = 0;
                }
            }
        }
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        RecyclerView.Adapter adapter = parent.getAdapter();
        if (adapter == null) {
            return;
        }

        int itemCount = adapter.getItemCount();
        boolean overlap = mOverlap;

        if (mOrientation == VERTICAL) {
            final boolean isRtl = ViewCompat.getLayoutDirection(parent) == ViewCompat.LAYOUT_DIRECTION_RTL;
            int mPaddingLeft;
            int mPaddingRight;
            if (isRtl) {
                mPaddingLeft = mPaddingEnd;
                mPaddingRight = mPaddingStart;
            } else {
                mPaddingLeft = mPaddingStart;
                mPaddingRight = mPaddingEnd;
            }

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

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

                boolean show;
                if (mShowDividerHelper != null) {
                    show = mShowDividerHelper.showDivider(position + 1);
                } else {
                    show = position != itemCount - 1 || mShowLastDivider;
                }
                if (show) {
                    int top = child.getBottom() + lp.bottomMargin;
                    if (overlap) {
                        top -= mThickness;
                    }
                    final int bottom = top + mThickness;
                    mRect.set(left, top, right, bottom);
                    c.drawRect(mRect, mPaint);
                }

                if (position == 0) {
                    if (mShowDividerHelper != null) {
                        show = mShowDividerHelper.showDivider(0);
                    } else {
                        show = mShowFirstDivider;
                    }
                    if (show) {
                        int bottom = child.getTop() + lp.topMargin;
                        if (overlap) {
                            bottom += mThickness;
                        }
                        final int top = bottom - mThickness;
                        mRect.set(left, top, right, bottom);
                        c.drawRect(mRect, mPaint);
                    }
                }
            }
        } else {
            final int top = parent.getPaddingTop() + mPaddingStart;
            final int bottom = parent.getHeight() - parent.getPaddingBottom() - mPaddingEnd;
            final int childCount = parent.getChildCount();

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

                boolean show;
                if (mShowDividerHelper != null) {
                    show = mShowDividerHelper.showDivider(position + 1);
                } else {
                    show = position != itemCount - 1 || mShowLastDivider;
                }
                if (show) {
                    int left = child.getRight() + lp.rightMargin;
                    if (overlap) {
                        left -= mThickness;
                    }
                    final int right = left + mThickness;
                    mRect.set(left, top, right, bottom);
                    c.drawRect(mRect, mPaint);
                }

                if (position == 0) {
                    if (mShowDividerHelper != null) {
                        show = mShowDividerHelper.showDivider(0);
                    } else {
                        show = mShowFirstDivider;
                    }
                    if (show) {
                        int right = child.getLeft() + lp.leftMargin;
                        if (overlap) {
                            right += mThickness;
                        }
                        final int left = right - mThickness;
                        mRect.set(left, top, right, bottom);
                        c.drawRect(mRect, mPaint);
                    }
                }
            }
        }
    }

    public interface ShowDividerHelper {
        boolean showDivider(int index);
    }
}