在控件RecyclerView中,分割線DividerItemDecoration類的使用經常見,如果是使用自帶的分割線,只需要這樣寫即可
RecyclerView mRecyclerView; mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
會出現一條1pd的灰色的分割線,但是我如果想自己寫自定義的分割線呢,這個時候需要我們自定義一個shape,在里面進行自定義樣式然后進行引用
代碼如下:divider.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#CB8589" />
<size android:height="15dp" />
</shape>
那我怎么在我的java里面用呢,代碼如下:
//添加自定義的分割線 DividerItemDecoration divider = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL); divider.setDrawable(ContextCompat.getDrawable(this, R.drawable.divider)); mRecyclerView.addItemDecoration(divider);
如此,我的模擬器上就出現了又粗又紅的分割線
但是這個時候又有問題,我每個子項都有,那么我如果想最后一個不要分割線呢,這個時候,我打開了DividerItemDecoration類的源碼,發現了循環的地方
我只需要把這個地方減1,那么我不就可以刪去最后一個子項的分割線了嗎,顯然,改源碼是很不合理的,於是,我新建一個GridItemDecoration的類,修改如下:
GridItemDecoration.java
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.example.administrator.myapplication; 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.NonNull; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.ItemDecoration; import android.support.v7.widget.RecyclerView.State; import android.util.Log; import android.view.View; public class GridItemDecoration extends ItemDecoration { public static final int HORIZONTAL = 0; public static final int VERTICAL = 1; private static final String TAG = "DividerItem"; private static final int[] ATTRS = new int[]{16843284}; private Drawable mDivider; private int mOrientation; private final Rect mBounds = new Rect(); public GridItemDecoration(Context context, int orientation) { TypedArray a = context.obtainStyledAttributes(ATTRS); this.mDivider = a.getDrawable(0); if (this.mDivider == null) { Log.w("DividerItem", "@android:attr/listDivider was not set in the theme used for this DividerItemDecoration. Please set that attribute all call setDrawable()"); } a.recycle(); this.setOrientation(orientation); } public void setOrientation(int orientation) { if (orientation != 0 && orientation != 1) { throw new IllegalArgumentException("Invalid orientation. It should be either HORIZONTAL or VERTICAL"); } else { this.mOrientation = orientation; } } public void setDrawable(@NonNull Drawable drawable) { if (drawable == null) { throw new IllegalArgumentException("Drawable cannot be null."); } else { this.mDivider = drawable; } } public void onDraw(Canvas c, RecyclerView parent, State state) { if (parent.getLayoutManager() != null && this.mDivider != null) { if (this.mOrientation == 1) { this.drawVertical(c, parent); } else { this.drawHorizontal(c, parent); } } } 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 - 1; ++i) { View child = parent.getChildAt(i); parent.getDecoratedBoundsWithMargins(child, this.mBounds); int bottom = this.mBounds.bottom + Math.round(child.getTranslationY()); int top = bottom - this.mDivider.getIntrinsicHeight(); this.mDivider.setBounds(left, top, right, bottom); this.mDivider.draw(canvas); } canvas.restore(); } private void drawHorizontal(Canvas canvas, RecyclerView parent) { canvas.save(); int top; int bottom; if (parent.getClipToPadding()) { top = parent.getPaddingTop(); bottom = parent.getHeight() - parent.getPaddingBottom(); canvas.clipRect(parent.getPaddingLeft(), top, parent.getWidth() - parent.getPaddingRight(), bottom); } else { top = 0; bottom = parent.getHeight(); } int childCount = parent.getChildCount(); for (int i = 0; i < childCount; ++i) { View child = parent.getChildAt(i); parent.getLayoutManager().getDecoratedBoundsWithMargins(child, this.mBounds); int right = this.mBounds.right + Math.round(child.getTranslationX()); int left = right - this.mDivider.getIntrinsicWidth(); this.mDivider.setBounds(left, top, right, bottom); this.mDivider.draw(canvas); } canvas.restore(); } public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) { if (this.mDivider == null) { outRect.set(0, 0, 0, 0); } else { if (this.mOrientation == 1) { outRect.set(0, 0, 0, this.mDivider.getIntrinsicHeight()); } else { outRect.set(0, 0, this.mDivider.getIntrinsicWidth(), 0); } } } }
如此,我在activity里面把這個類引進就可以:
//最后一個不顯示分割線且自定義分割線 GridItemDecoration gridItemDecoration = new GridItemDecoration(this, DividerItemDecoration.VERTICAL); gridItemDecoration.setDrawable(ContextCompat.getDrawable(this, R.drawable.divider)); mRecyclerView.addItemDecoration(gridItemDecoration);
完整代碼如下:
package com.example.administrator.myapplication; import android.content.ContextWrapper; import android.graphics.Paint; import android.os.Bundle; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.RecyclerView; import java.util.List; import java.util.ArrayList; public class BodyActivity extends AppCompatActivity { RecyclerView mRecyclerView; public Paint paint; @Override protected void onCreate(Bundle saveInstanceState) { super.onCreate(saveInstanceState); setContentView(R.layout.activity_body); //1.獲取控件 mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); //設置布局方式 mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));//線性布局 // mRecyclerView.setLayoutManager(new GridLayoutManager(this,2));//網格布局 mRecyclerView.setHasFixedSize(true); //是否重新計算大小 //3.准備數據 List<News> newsList = new ArrayList<>(); News news; for (int i = 1; i <= 20; i++) { news = new News(); news.setNewsTitle("java是世界上最好的語言" + i); news.setNewsSource("新華網" + i); news.setPublishTime("2018-8-6"); newsList.add(news); } //添加Android自帶的分割線 // mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL)); //添加自定義的分割線 // DividerItemDecoration divider = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL); // divider.setDrawable(ContextCompat.getDrawable(this, R.drawable.divider)); // mRecyclerView.addItemDecoration(divider); //最后一個不顯示分割線且自定義分割線 GridItemDecoration gridItemDecoration = new GridItemDecoration(this, DividerItemDecoration.VERTICAL); gridItemDecoration.setDrawable(ContextCompat.getDrawable(this, R.drawable.divider)); mRecyclerView.addItemDecoration(gridItemDecoration); //4.准備適配器 NewsAdapter newsAdapter = new NewsAdapter(newsList); mRecyclerView.setAdapter(newsAdapter); } }