RecyclerView自定义分割线

前言

RecyclerView已经推出很久了,由于其高度的可定制性现在被广泛应用,我们常用的功能,如:单条目更新,LayoutManager实现各种炫酷的排列效果,定义个性分割线等

今天学习如何定制一个自己的分割线,让你的列表看起来更好看

内容部分

首先:常规的用法三步走设置布局方式,设置分割线,设置adapter。

本身系统是自带了一个默认的分割线类DividerItemDecoration可以实现和ListView一样的效果。但是我们可能有其他的需求,如我们希望分割线有不同的颜色,这时我们可以通过DividerItemDecoration的setDrawable(Drawable drawable)方法设置一个Drawable进入,如下:

DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
  Drawable drawable = getResources().getDrawable(R.drawable.mycoler);
  dividerItemDecoration.setDrawable(drawable);
  recyclerView.addItemDecoration(dividerItemDecoration);

通过编写不同的shape可以设置成不同的颜色的线。如图:

特殊情况问题记录

当我在绘制横向滚动的RecyclerView的分割线的时候,出了一个小问题,因为使用shape画的线,获取Drawable的宽度一直为1px导致,无法显示分割线,如果你传入的是一个图片就没问题,我还没找到原因。

描述:RecyclerView高度为100dp,item的高度为50dp,当绘制出竖直方向分割线的时候,item部分分割线未能显示,经过排查发现,分割线是绘制在RecyclerView的view上,item作为子view存在于RecyclerView的容器中,所以导致分割线绘制的一部分被遮挡,此处我使用系统提供的DividerItemDecoration也是效果一致的。如下图:

所绘制的分割线上绘制在RecyclerView的布局上的,这也就解释了,为什么绘制完分割线需要调用getItemOffsets()方法进行位置重新排列了

如何解决这个情况呢?(其实就是自己根据出传入的Drawable宽度处理)

1.给item设置一个padding值就可以了,这样就可以把分割线显示出来了。

2.通过getItemOffsets()方法设置偏移量,让item顺位后移,显示出来分割线即可。

处理后的图片如下:

不过这个问题我会在尝试,找出为什么拿到的宽度数值不正确,如有知道的大佬,望告知,谢谢

定制过程分析

步骤一

初始化一些参数内容,如偏移量,默认的分割线等

public MyItemDecoration(Context context, int orientation, int inset, Drawable drawable) {
  if (orientation != VERTICAL && orientation != HORIZONTAL) {
   throw new IllegalArgumentException("请输入正确的参数!");
  }
  this.inset = inset;
  mOrientation = orientation;
  mDivider = drawable;
  if (drawable == null) {
   final TypedArray a = context.obtainStyledAttributes(ATTRS);
   mDivider = a.getDrawable(0);
   a.recycle();
  }
 }

步骤二

绘制部分,通过标识位来区分是垂直方向还是水平方向

@Override
 public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
  if (parent.getLayoutManager() != null && this.mDivider != null) {
   if (this.mOrientation == VERTICAL) {
    this.drawVertical(c, parent);
   } else {
    this.drawHorizontal(c, parent);
   }

  }
 }

步骤三

绘制垂直或水平的分割线,这里主要是设置Drawable在RecyclerView中的位置。

private void drawHorizontal(Canvas canvas, RecyclerView parent) {
  int top = parent.getPaddingTop();
  int bottom = parent.getHeight() - parent.getPaddingBottom();

  int childCount = parent.getChildCount();
  for (int i = 0; i < childCount - 1; i++) {
   View childAt = parent.getChildAt(i);
   RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) childAt.getLayoutParams();
   int left = childAt.getRight() + layoutParams.rightMargin;
   int right = mDivider.getIntrinsicWidth() + left;

   mDivider.setBounds(left, top, right, bottom);
   mDivider.draw(canvas);

  }

 }

 private void drawVertical(Canvas canvas, RecyclerView parent) {
  int left = parent.getPaddingLeft();
  int right = parent.getWidth() - parent.getPaddingRight();
  int childCount = parent.getChildCount();
  for (int i = 0; i < childCount - 1; i++) {
   View child = parent.getChildAt(i);
   RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
   int top = child.getBottom() + layoutParams.bottomMargin;
   int bottom = top + mDivider.getIntrinsicHeight();

   if (inset > 0) {
    mDivider.setBounds(left + inset, top, right - inset, bottom);
   } else {
    mDivider.setBounds(left, top, right, bottom);
   }
   mDivider.draw(canvas);
  }
 }

步骤四

因为我们为RecyclerView添加了分割线,所以整体位置要做调整。主要调整的部分就是,在条目中间添加一个分割线,需要对原来的所有条目后移动一个分割线的宽度(高度)。

 @Override
 public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
  if (this.mDivider == null) {
   outRect.set(0, 0, 0, 0);
  } else {
   if (this.mOrientation == VERTICAL) {
    outRect.set(0, 0, 0, this.mDivider.getIntrinsicHeight());
   } else {
    outRect.set(0, 0, this.mDivider.getIntrinsicWidth(), 0);
   }

  }
 }

以上就是基本的步骤的,其实就是参考系统提供的DividerItemDecoration来写就行。其实系统的代码,是最好的实例,所以多读源码对能力的提升很有帮助。

另外一种实现分割线的方式

其实这种方式很简单,就是将分割线放到item布局中。感觉也是不错的方案,毕竟在做条目布局的时候就把这个分割线完成了。

finish以上完毕,有问题谢谢指出。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • RecyclerView底部分割线去除的方法

    概述 之前我们抛出了一个问题就是RecyclerView在显示列表的时候,最底部也就是最后一个Item后面还有分割线,这大大影响界面的美观.这篇文章就是解决这个问题的. 自定义分割线 通过分析源码后我们发现没有相关的方法来处理这一需求,所以只能自定义分割线,通过上一篇文章的基础我们知道肯定是修改getItemOffsets.那我们的思路是让这个方法在到最后一个条目时,不偏移分割线的间隙.同时也要修改onDraw方法,让他不再绘制最后一条分割线. private void drawHorizont

  • android中RecyclerView自定义分割线实现

    最近一直在看RecyclerView,较之ListView它确实是灵活多变,给予开发者更多自定义的空间,比如:需要添加头部和尾部.item的点击事件.自定义的LayoutManager,还有就是下面要说的自定义的分割线. 1.如何理解分割线 经常听到有人说自定义分割线麻烦,为什么不把分割线写到item布局里,这样不是更简单吗?有些情况把分割线写到item布局里是很难达到我们想要的效果,例如RecyclerView里的GridLayoutManager,StaggeredGridLayoutMan

  • Android 给RecyclerView添加分割线的具体步骤(分享)

    [吐槽]RecyclerView没有提供分割线的方法,想要加个线还要自己画,点击事件的监听都要自己实现,不过真的好用. 给RecyclerView添加分割线的步骤 1.新建类继承于RecyclerView.ItemDecoration,此为是抽象类: public static abstract class ItemDecoration { public void onDraw(Canvas c, RecyclerView parent, State state) { onDraw(c, par

  • RecyclerView的万能分割线

    什么是RecyclerView RecyclerView是Android 5.0 materials design中的组件之一,相应的还有CardView.Palette等.看名字我们就能看出一点端倪,没错,它主要的特点就是复用.我们知道,Listview中的Adapter中可以实现ViewHolder的复用.RecyclerView提供了一个耦合度更低的方式来复用ViewHolder,并且可以轻松的实现ListView.GridView以及瀑布流的效果. 先给大家展示下效果图: 使用方法: 添

  • Android实现RecyclerView添加分割线的简便方法

    1.前言 刚开始学习RecyclerView的时候我跟着一个视频学的,当时添加分割线是从外面导入一个Java类,然后使用里面的函数来创建分割线的,所以一直以来我都是这样做的.直到前几天才无意中发现,原来v7包中提供了一个DividerItemDecoration类,利用它,我们可以很简单地实现RecyclerView的分割线!那还等什么呢?赶紧用起来. 2.创建一个简单的RecyclerView 首先当然应该来一个RecyclerView,这里就不再赘述了,随便造点数据就好.直接上代码: pub

  • 万能RecyclerView分割线

    就不多叙述了,直接上代码 import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import andr

  • Android中RecyclerView上拉下拉,分割线,多条目的实例代码

    //activity的xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity

  • RecyclerView消除底部分割线的方法

    最近遇到一个问题,用RecyclerView显示数据,纵向列表显示,添加默认分割线. 问题是:底部也会显示分割线,这很影响美观. 怎么解决这个问题呢?我想了很多办法,毫无头绪... 最后,查看默认分割线的类DividerItemDecoration的源码: public class DividerItemDecoration extends ItemDecoration { private static final int[] ATTRS = new int[]{16843284}; publi

  • Android RecyclerView实现水平、垂直方向分割线

    android RecyclerView不像过去的ListView那样随意的设置水平方向的分割线,如果要实现RecyclerView的水平/垂直分割线,则需要继承自RecyclerView.ItemDecoration重写getItemOffsets方法,从而增加水平/垂直分割线. 写一个例子. MainActivity.Java: package zhangphil.app; import android.content.Context; import android.graphics.Col

  • Android RecyclerView网格布局(支持多种分割线)详解(2)

    上篇Android RecyclerView 详解(1)-线性布局 记录了下RecyclerView的使用方法,并且讲述了线性布局列表的使用方法,在此基础上加上了万能分割线,支持颜色分割线和图片分割线,同时支持对分割线设置线宽. 这篇是总结一下网格布局的使用,同样也支持两种分割线和线宽的设置. 主要的相关类: 1. RecyclerView.Adapter 2. GridLayoutManager 网格布局管理器 3. RecycleView.ItemDecoration 分割线 下面就直接通过

随机推荐