android控件RecyclerView中,如何显示自定义分割线以及最后一项去除分割线
在控件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); } }