java DividerItemDecoration。 RecyclerView.ItemDecoration简单实现

Posted

tags:

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

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

    private Drawable mDivider;
    private boolean mShowFirstDivider = false;
    private boolean mShowLastDivider = false;

    int mOrientation = -1;

    public DividerItemDecoration(Context context, AttributeSet attrs) {
        final TypedArray a = context
            .obtainStyledAttributes(attrs, new int[]{android.R.attr.listDivider});
        mDivider = a.getDrawable(0);
        a.recycle();
    }

    public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
        boolean showLastDivider) {
        this(context, attrs);
        mShowFirstDivider = showFirstDivider;
        mShowLastDivider = showLastDivider;
    }

    public DividerItemDecoration(Context context, int resId) {
        mDivider = ContextCompat.getDrawable(context, resId);
    }

    public DividerItemDecoration(Context context, int resId, boolean showFirstDivider,
        boolean showLastDivider) {
        this(context, resId);
        mShowFirstDivider = showFirstDivider;
        mShowLastDivider = showLastDivider;
    }

    public DividerItemDecoration(Drawable divider) {
        mDivider = divider;
    }

    public DividerItemDecoration(Drawable divider, boolean showFirstDivider,
        boolean showLastDivider) {
        this(divider);
        mShowFirstDivider = showFirstDivider;
        mShowLastDivider = showLastDivider;
    }

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

        int position = parent.getChildAdapterPosition(view);
        if (position == RecyclerView.NO_POSITION || (position == 0 && !mShowFirstDivider)) {
            return;
        }

        if (mOrientation == -1)
            getOrientation(parent);

        if (mOrientation == LinearLayoutManager.VERTICAL) {
            outRect.top = mDivider.getIntrinsicHeight();
            if (mShowLastDivider && position == (state.getItemCount() - 1)) {
                outRect.bottom = outRect.top;
            }
        } else {
            outRect.left = mDivider.getIntrinsicWidth();
            if (mShowLastDivider && position == (state.getItemCount() - 1)) {
                outRect.right = outRect.left;
            }
        }
    }

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

        // Initialization needed to avoid compiler warning
        int left = 0, right = 0, top = 0, bottom = 0, size;
        int orientation = mOrientation != -1 ? mOrientation : getOrientation(parent);
        int childCount = parent.getChildCount();

        if (orientation == LinearLayoutManager.VERTICAL) {
            size = mDivider.getIntrinsicHeight();
            left = parent.getPaddingLeft();
            right = parent.getWidth() - parent.getPaddingRight();
        } else { //horizontal
            size = mDivider.getIntrinsicWidth();
            top = parent.getPaddingTop();
            bottom = parent.getHeight() - parent.getPaddingBottom();
        }

        for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

            if (orientation == LinearLayoutManager.VERTICAL) {
                top = child.getTop() - params.topMargin - size;
                bottom = top + size;
            } else { //horizontal
                left = child.getLeft() - params.leftMargin;
                right = left + size;
            }
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }

        // show last divider
        if (mShowLastDivider && childCount > 0) {
            View child = parent.getChildAt(childCount - 1);
            if (parent.getChildAdapterPosition(child) == (state.getItemCount() - 1)) {
                RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
                if (orientation == LinearLayoutManager.VERTICAL) {
                    top = child.getBottom() + params.bottomMargin;
                    bottom = top + size;
                } else { // horizontal
                    left = child.getRight() + params.rightMargin;
                    right = left + size;
                }
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }
        }
    }

    private int getOrientation(RecyclerView parent) {
        if (mOrientation == -1) {
            if (parent.getLayoutManager() instanceof LinearLayoutManager) {
                LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
                mOrientation = layoutManager.getOrientation();
            } else {
                throw new IllegalStateException(
                    "DividerItemDecoration can only be used with a LinearLayoutManager.");
            }
        }
        return mOrientation;
    }
}
# DividerItemDecoration

Simple RecyclerView ItemDecoration  
Based on [fatfingers](https://gist.github.com/fatfingers/233abbae200b5e87297b) implementation.

Fixed [lapastillaroja](https://gist.github.com/lapastillaroja/858caf1a82791b6c1a36) implementation with correct first and last item handling.

## Features
- Can use any drawable as divider
- Divider visible also at the beginning and end of the item's list (disabled by default)
- Only works with `LinearLayoutManager`

### New in this fork
- Can use resource id as drawable
- `SpaceItemDecoration` if you need only empty space between items

## Example

Default android divider
```java
mCategoryRecyclerView.addItemDecoration(
        new DividerItemDecoration(getActivity(), null));
```

Custom divider as drawable (deprecated) with first divider (before first element) and last divider (after last element)
```java
mCategoryRecyclerView.addItemDecoration(
        new DividerItemDecoration(getActivity().getDrawable(R.drawable.ic_launcher),
                true, true));
```

Custom divider as resource id
```java
mCategoryRecyclerView.addItemDecoration(
        new DividerItemDecoration(getActivity(), R.drawable.ic_launcher,
                true, true));
```

Space divider
```java
mCategoryRecyclerView.addItemDecoration(
        new SpaceItemDecoration(getActivity(), R.dimen.list_space,
                true, true));
```
import android.content.Context;
import android.graphics.Rect;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;

public class SpaceItemDecoration extends RecyclerView.ItemDecoration
{
	private final int mSpace;
	private boolean mShowFirstDivider = false;
	private boolean mShowLastDivider = false;

	int mOrientation = -1;

	public SpaceItemDecoration(Context context, AttributeSet attrs) {
		mSpace = 0;
	}
	public SpaceItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
		boolean showLastDivider) {
		this(context, attrs);
		mShowFirstDivider = showFirstDivider;
		mShowLastDivider = showLastDivider;
	}

	public SpaceItemDecoration(int spaceInPx)
	{
		mSpace = spaceInPx;
	}
	public SpaceItemDecoration(int spaceInPx, boolean showFirstDivider,
		boolean showLastDivider)
	{
		this(spaceInPx);
		mShowFirstDivider = showFirstDivider;
		mShowLastDivider = showLastDivider;
	}

	public SpaceItemDecoration(Context ctx, int resId)
	{
		mSpace = ctx.getResources().getDimensionPixelSize(resId);
	}
	public SpaceItemDecoration(Context ctx, int resId, boolean showFirstDivider,
		boolean showLastDivider)
	{
		this(ctx, resId);
		mShowFirstDivider = showFirstDivider;
		mShowLastDivider = showLastDivider;
	}

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

		if (mOrientation == -1)
			getOrientation(parent);

		int position = parent.getChildAdapterPosition(view);
		if (position == RecyclerView.NO_POSITION || (position == 0 && !mShowFirstDivider)) {
			return;
		}

		if (mOrientation == LinearLayoutManager.VERTICAL) {
			outRect.top = mSpace;
			if (mShowLastDivider && position == (state.getItemCount() - 1)) {
				outRect.bottom = outRect.top;
			}
		} else {
			outRect.left = mSpace;
			if (mShowLastDivider && position == (state.getItemCount() - 1)) {
				outRect.right = outRect.left;
			}
		}
	}

	private int getOrientation(RecyclerView parent) {
		if (mOrientation == -1) {
			if (parent.getLayoutManager() instanceof LinearLayoutManager) {
				LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
				mOrientation = layoutManager.getOrientation();
			} else {
				throw new IllegalStateException(
					"DividerItemDecoration can only be used with a LinearLayoutManager.");
			}
		}
		return mOrientation;
	}
}

以上是关于java DividerItemDecoration。 RecyclerView.ItemDecoration简单实现的主要内容,如果未能解决你的问题,请参考以下文章

Java 布尔运算

java [Java] Java常用代码#java

Java - 35 Java 实例

Java While 循环

Java 字符串

Java If ... Else