1上一篇仿微信圖片選擇器的時候分割線出了點bug,其實是我把一塊關鍵代碼刪掉了,不過無關緊要,這次單獨寫一篇 2csdn上hongyang大神已經寫過了,但是按照他寫的方法我自己試了一下網格佈局的有點問題,具體是什麼問題已經記不清了(沒有質疑大神代碼的意思,貌似是他的代碼有一個方法過期了),我這個是 ...
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里,然後一行代碼調用