Android Recyclerview 網格布局分割線

2018-03-02 08:28:58來源:cnblogs.com作者:付斌人點擊

分享

1上一篇仿微信圖片選擇器的時候分割線出了點bug,其實是我把一塊關鍵代碼刪掉了,不過無關緊要,這次單獨寫一篇

2csdn上hongyang大神已經寫過了,但是按照他寫的方法我自己試了一下網格布局的有點問題,具體是什么問題已經記不清了(沒有質疑大神代碼的意思,貌似是他的代碼有一個方法過期了),我這個是自己親測沒問題的

3步驟,新建一個DiciderGridItemDecoration

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.annotation.IntDef;import android.support.v4.view.ViewCompat;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.StaggeredGridLayoutManager;import android.util.SparseArray;import android.util.SparseIntArray;import android.view.View;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;/** * Created by MAC on 2018/2/5. */public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {    private static final int[] ATTRS = new int[]{android.R.attr.listDivider}; //這個就是設置樣式的地方(顏色,寬度等等)    public static final int GRID_DIVIDER_HORIZONTAL = GridLayoutManager.HORIZONTAL;    public static final int GRID_DIVIDER_VERTICAL = GridLayoutManager.VERTICAL;    private final SparseIntArray mHorizontalDividerOffsets = new SparseIntArray();    private final SparseIntArray mVerticalDividerOffsets = new SparseIntArray();    private final SparseArray<DrawableCreator> mTypeDrawableFactories = new SparseArray<>();    @IntDef({            GRID_DIVIDER_HORIZONTAL,            GRID_DIVIDER_VERTICAL    })    @Retention(RetentionPolicy.SOURCE)    private @interface Orientation {    }    @Orientation    private int mOrientation;    private Drawable mHorizontalDivider;    private Drawable mVerticalDivider;    public DividerGridItemDecoration(Context context, @Orientation int orientation) {        resolveDivider(context);        setOrientation(orientation);    }    private void resolveDivider(Context context) {        final TypedArray a = context.obtainStyledAttributes(ATTRS);        mVerticalDivider = mHorizontalDivider = a.getDrawable(0);        a.recycle();    }    public void setOrientation(int orientation) {        this.mOrientation = orientation;    }    public void setVerticalDivider(Drawable verticalDivider) {        this.mVerticalDivider = verticalDivider;    }    public void setHorizontalDivider(Drawable horizontalDivider) {        this.mHorizontalDivider = horizontalDivider;    }    @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        drawHorizontalDividers(c, parent);        drawVerticalDividers(c, parent);    }    @Override    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {        final int spanCount = getSpanCount(parent);        final int childCount = parent.getAdapter().getItemCount();        final int adapterPosition = parent.getChildAdapterPosition(view);        if (mHorizontalDividerOffsets.indexOfKey(adapterPosition) < 0) {            mHorizontalDividerOffsets.put(adapterPosition, getHorizontalDivider(parent, adapterPosition).getIntrinsicHeight());        }        if (mVerticalDividerOffsets.indexOfKey(adapterPosition) < 0) {            mVerticalDividerOffsets.put(adapterPosition, getVerticalDivider(parent, adapterPosition).getIntrinsicHeight());        }        outRect.set(0, 0, mHorizontalDividerOffsets.get(adapterPosition), mVerticalDividerOffsets.get(adapterPosition));        if (isLastRow(adapterPosition, spanCount, childCount)) {            outRect.bottom = 0;        }        if (isLastColumn(adapterPosition, spanCount, childCount)) {            outRect.right = 0;        }    }    private boolean isLastColumn(int position, int spanCount, int childCount) {        if (mOrientation == GRID_DIVIDER_VERTICAL) {            return (position + 1) % spanCount == 0;        } else {            int lastColumnCount = childCount % spanCount;            lastColumnCount = lastColumnCount == 0 ? spanCount : lastColumnCount;            return position >= childCount - lastColumnCount;        }    }    private boolean isLastRow(int position, int spanCount, int childCount) {        if (mOrientation == GRID_DIVIDER_VERTICAL) {            int lastColumnCount = childCount % spanCount;            lastColumnCount = lastColumnCount == 0 ? spanCount : lastColumnCount;            return position >= childCount - lastColumnCount;        } else {            return (position + 1) % spanCount == 0;        }    }    private int getSpanCount(RecyclerView parent) {        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof GridLayoutManager) {            return ((GridLayoutManager) layoutManager).getSpanCount();        } else if (layoutManager instanceof StaggeredGridLayoutManager) {            return ((StaggeredGridLayoutManager) layoutManager).getSpanCount();        } else {            throw new UnsupportedOperationException("the GridDividerItemDecoration can only be used in " +                    "the RecyclerView which use a GridLayoutManager or StaggeredGridLayoutManager");        }    }    public void drawVerticalDividers(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 Drawable divider = getVerticalDivider(parent, params.getViewAdapterPosition());            final int top = child.getBottom() + params.bottomMargin + Math.round(ViewCompat.getTranslationY(child));            final int bottom = top + divider.getIntrinsicHeight();            mVerticalDividerOffsets.put(params.getViewAdapterPosition(), divider.getIntrinsicHeight());            divider.setBounds(left, top, right, bottom);            divider.draw(c);        }    }    public void drawHorizontalDividers(Canvas c, RecyclerView parent) {        final int top = parent.getPaddingTop();        final int bottom = parent.getHeight() - parent.getPaddingBottom();        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 Drawable divider = getHorizontalDivider(parent, params.getViewAdapterPosition());            final int left = child.getRight() + params.rightMargin + Math.round(ViewCompat.getTranslationX(child));            final int right = left + divider.getIntrinsicHeight();            mHorizontalDividerOffsets.put(params.getViewAdapterPosition(), divider.getIntrinsicHeight());            divider.setBounds(left, top, right, bottom);            divider.draw(c);        }    }    private Drawable getVerticalDivider(RecyclerView parent, int adapterPosition) {        RecyclerView.Adapter adapter = parent.getAdapter();        int itemType = adapter.getItemViewType(adapterPosition);        DrawableCreator drawableCreator = mTypeDrawableFactories.get(itemType);        if (drawableCreator != null) {            return drawableCreator.createVertical(parent, adapterPosition);        }        return mVerticalDivider;    }    private Drawable getHorizontalDivider(RecyclerView parent, int adapterPosition) {        RecyclerView.Adapter adapter = parent.getAdapter();        int itemType = adapter.getItemViewType(adapterPosition);        DrawableCreator drawableCreator = mTypeDrawableFactories.get(itemType);        if (drawableCreator != null) {            return drawableCreator.createHorizontal(parent, adapterPosition);        }        return mHorizontalDivider;    }    public void registerTypeDrawable(int itemType, DrawableCreator drawableCreator) {        mTypeDrawableFactories.put(itemType, drawableCreator);    }    public interface DrawableCreator {        Drawable createVertical(RecyclerView parent, int adapterPosition);        Drawable createHorizontal(RecyclerView parent, int adapterPosition);    }}

4下一步 在drawable文件夾下新建分割線樣式 ,divider_bg.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle" >    <gradient //說來慚愧,這個是設置漸變色的,為了省事我直接把三個色改成相同顏色(正常寫corners,solid,stroke這些應該也是可以的我自己沒試)        android:centerColor="#F5F6F6"        android:endColor="#F5F6F6"        android:startColor="#F5F6F6"        android:type="linear" />    <size android:height="4dp"/></shape>

5下一步 在manifests 的 application里找到them,點擊進入并修改

<style name="PlayerTheme" parent="Theme.AppCompat.NoActionBar">        <item name="android:windowAnimationStyle">@style/PlayerAnimation</item>        <item name="android:listDivider">@drawable/divider_bg</item>//主要就是加上這句話,其他的代碼跟分割線無關(具體的可以看hongyang大神的博客)    </style>

6使用

binding.recyclerview.setLayoutManager(new GridLayoutManager(context, 2));binding.recyclerview.addItemDecoration(new DividerGridItemDecoration(context, DividerGridItemDecoration.GRID_DIVIDER_VERTICAL));//最后這個參數應該就是設置分割線的方向的,如果是不變色的分割線怎么設置無所謂,變色的線就自己決定方向吧

7總結一下,其實非常的簡單,把DividerGridItemDecoration復制一下,寫一個樣式,把樣式添加到them里,然后一行代碼調用

相關文章

    無相關信息

微信掃一掃

第七城市微信公眾平臺
捕鱼达人小游戏