解决RecycleView分割线不居中的三种方法

本文为大家分享了三种RecycleView分割线不居中的解决方法,供大家参考,具体内容和如下

方法一:

public class SpacesItemDecoration extends RecyclerView.ItemDecoration {

  private int mSpace;
  private int mSpanCount; // RecyclerView有多少列
  private boolean mHasPadding; // RecyclerView是否有Padding

  public SpacesItemDecoration(int mSpace) {
    this.mSpace = mSpace;
    this.mHasPadding = true;
  }

  public SpacesItemDecoration(int mSpace, boolean hasPadding) {
    this.mSpace = mSpace;
    this.mHasPadding = hasPadding;
  }

  @Override
  public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    // 初始化列数
    if (mSpanCount == 0) {
      this.mSpanCount = ((GridLayoutManager) parent.getLayoutManager()).getSpanCount();
    }
    int position = parent.getChildAdapterPosition(view); // item position
    int column = position % mSpanCount; // item column

    if (mHasPadding) {
      outRect.left = mSpace - column * mSpace / mSpanCount; // spacing - column * ((1f / spanCount) * spacing)
      outRect.right = (column + 1) * mSpace / mSpanCount; // (column + 1) * ((1f / spanCount) * spacing)
      if (position < mSpanCount) { // top edge
        outRect.top = mSpace;
      }
      outRect.bottom = mSpace; // item bottom
    } else {
      outRect.left = column * mSpace / mSpanCount; // column * ((1f / spanCount) * spacing)
      outRect.right = mSpace - (column + 1) * mSpace / mSpanCount; // spacing - (column + 1) * ((1f /  spanCount) * spacing)
      if (position >= mSpanCount) {
        outRect.top = mSpace; // item top
      }
    }
  }

  public void setHasPadding(boolean hasPadding) {
    this.mHasPadding = hasPadding;
  }

}

方法二:

public class MutiItemDecoration extends RecyclerView.ItemDecoration {

  public enum Type {
    VERTICAL, HORIZONTAL, ALL
  }

  private Type type;//分割线类型
  private int dividerSize = 10;//分割线尺寸

  public MutiItemDecoration(MutiItemDecoration.Type type, int dividerSize) {
    this.type = type;
    this.dividerSize = dividerSize;
  }

  @Override
  public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
    int spanCount = getSpanCount(parent);
    int childCount = parent.getAdapter().getItemCount();

    switch (type) {
      case ALL:
        if (itemPosition % spanCount == 0) {//第一列
          if (isLastRaw(parent, itemPosition, spanCount, childCount)) {
            outRect.set(0, 0, dividerSize / 2, 0);
          } else {
            outRect.set(0, 0, dividerSize / 2, dividerSize);
          }
        } else if (itemPosition % spanCount == spanCount - 1) {//最后一列
          if (isLastRaw(parent, itemPosition, spanCount, childCount)) {
            outRect.set(dividerSize / 2, 0, 0, 0);
          } else {
            outRect.set(dividerSize / 2, 0, 0, dividerSize);
          }
        } else {//中间列
          if (isLastRaw(parent, itemPosition, spanCount, childCount)) {
            outRect.set(dividerSize / 2, 0, dividerSize / 2, 0);
          } else {
            outRect.set(dividerSize / 2, 0, dividerSize / 2, dividerSize);
          }
        }
        break;
      case VERTICAL:
        if (isLastRaw(parent, itemPosition, spanCount, childCount)) {
          outRect.set(0, 0, 0, 0);
        } else {
          outRect.set(0, 0, 0, dividerSize);
        }
        break;
      case HORIZONTAL:
        if (isLastColum(parent, itemPosition, spanCount, childCount)) {
          outRect.set(0, 0, 0, 0);
        } else {
          outRect.set(0, 0, dividerSize, 0);
        }
        break;
    }
  }

  // 是否是最后一列
  private boolean isLastColum(RecyclerView parent, int pos, int spanCount, int childCount) {
    RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
    if (layoutManager instanceof GridLayoutManager) {
      if ((pos + 1) % spanCount == 0)
        return true;
    } else {
      if (pos == childCount - 1)
        return true;
    }
    return false;
  }

  // 是否是最后一行
  private boolean isLastRaw(RecyclerView parent, int pos, int spanCount, int childCount) {
    RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
    if (layoutManager instanceof GridLayoutManager) {
      childCount = childCount - childCount % spanCount;
      if (pos >= childCount)
        return true;
    } else {
      if (pos == childCount - 1)
        return true;
    }
    return false;
  }

  //返回列数
  private int getSpanCount(RecyclerView parent) {
    RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
    if (layoutManager instanceof GridLayoutManager) {
      return ((GridLayoutManager) layoutManager).getSpanCount();
    }
    return -1;
  }

}

方法三:(目前只支持2列)

public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {

  private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
  private Drawable mDivider;

  public DividerGridItemDecoration(Context context) {
    final TypedArray a = context.obtainStyledAttributes(ATTRS);
    mDivider = ContextCompat.getDrawable(context, R.drawable.shape_divider);
    a.recycle();
  }

  @Override
  public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {

    drawHorizontal(c, parent);
    drawVertical(c, parent);

  }

  private int getSpanCount(RecyclerView parent) {
    // 列数
    int spanCount = -1;
    RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
    if (layoutManager instanceof GridLayoutManager) {

      spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
    } else if (layoutManager instanceof StaggeredGridLayoutManager) {
      spanCount = ((StaggeredGridLayoutManager) layoutManager)
          .getSpanCount();
    }
    return spanCount;
  }

  public void drawHorizontal(Canvas c, RecyclerView parent) {
    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 int left = child.getLeft() - params.leftMargin;
      final int right = child.getRight() + params.rightMargin
          + mDivider.getIntrinsicWidth();
      final int top = child.getBottom() + params.bottomMargin;
      final int bottom = top + mDivider.getIntrinsicHeight();
      mDivider.setBounds(left, top, right, bottom);
      mDivider.draw(c);
    }
  }

  public void drawVertical(Canvas c, RecyclerView parent) {
    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();

      if (i % 2 == 1) {
        final int top = child.getTop() - params.topMargin;
        final int bottom = child.getBottom() + params.bottomMargin;
        final int left = child.getLeft() - params.rightMargin;
        final int right = left + mDivider.getIntrinsicWidth() / 2;
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
      } else {
        final int top = child.getTop() - params.topMargin;
        final int bottom = child.getBottom() + params.bottomMargin;
        final int left = child.getRight() + params.rightMargin;
        final int right = left + mDivider.getIntrinsicWidth() / 2;
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
      }

      final int top = child.getTop() - params.topMargin;
      final int bottom = child.getBottom() + params.bottomMargin;
      final int left = child.getRight() + params.rightMargin;
      final int right = left + mDivider.getIntrinsicWidth();

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

  private boolean isLastColum(RecyclerView parent, int pos, int spanCount,
                int childCount) {
    RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
    if (layoutManager instanceof GridLayoutManager) {
      if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
      {
        return true;
      }
    } else if (layoutManager instanceof StaggeredGridLayoutManager) {
      int orientation = ((StaggeredGridLayoutManager) layoutManager)
          .getOrientation();
      if (orientation == StaggeredGridLayoutManager.VERTICAL) {
        if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
        {
          return true;
        }
      } else {
        childCount = childCount - childCount % spanCount;
        if (pos >= childCount)// 如果是最后一列,则不需要绘制右边
          return true;
      }
    }
    return false;
  }

  private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,
               int childCount) {
    RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
    if (layoutManager instanceof GridLayoutManager) {
      childCount = childCount - childCount % spanCount;
      if (pos >= childCount)// 如果是最后一行,则不需要绘制底部
        return true;
    } else if (layoutManager instanceof StaggeredGridLayoutManager) {
      int orientation = ((StaggeredGridLayoutManager) layoutManager)
          .getOrientation();
      // StaggeredGridLayoutManager 且纵向滚动
      if (orientation == StaggeredGridLayoutManager.VERTICAL) {
        childCount = childCount - childCount % spanCount;
        // 如果是最后一行,则不需要绘制底部
        if (pos >= childCount)
          return true;
      } else
      // StaggeredGridLayoutManager 且横向滚动
      {
        // 如果是最后一行,则不需要绘制底部
        if ((pos + 1) % spanCount == 0) {
          return true;
        }
      }
    }
    return false;
  }

  @Override
  public void getItemOffsets(Rect outRect, int itemPosition,
                RecyclerView parent) {
    int spanCount = getSpanCount(parent);
    int childCount = parent.getAdapter().getItemCount();
    if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部
    {
      outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
    } else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边
    {
      outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
    } else {
      outRect.set(0, 0, mDivider.getIntrinsicWidth(),
          mDivider.getIntrinsicHeight());
    }
  }
}

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

(0)

相关推荐

  • Android 关于ExpandableListView去掉里头分割线的方法

    关于ExpandableListView, 自己写了个类继承自BaseExpandableListAdapter groups,childs 都弄好了,显示出来的效果跟网上很多demo一样,我现在就是想去掉那个组下面各item间的分割线 有知道的么? ------解决方案-------------------- expandableList.setDivider(null); up,还不行就设置一个透明的颜色. ------解决方案-------------------- 可以的, androi

  • iOS应用开发中UITableView的分割线的一些设置技巧

    对于ios7,ios8及以上来说,调整UITableView的cell的分割线位置已经是相当不便,因为UITableView内部使用了margin layout. 其实只需要如下这样子就可以实现分割线的控制. 复制代码 代码如下: -(void)tableView:(UITableView )tableView willDisplayCell:(UITableViewCell )cell forRowAtIndexPath:(NSIndexPath *)indexPath {     // 下面

  • iOS开发之TableView实现完整的分割线详解

    前言 在我们创建一个tableView的时候,细心的你有没有发现UITableViewCell左侧会有空白.而我们在开发中有这样的需求: 需要一根完整的分割线(去掉烦人的空白部分, 即分割线的宽度 == 屏幕的宽度). 那么下面我就讲一讲该如何去掉空白的部分,显示完整的分割线. 这里我提供两种方法 : 第一种方法,也是我们最常用的方法,也是在我们自定义cell的时候所用到的. 即去掉tableView默认的分割线,自定义cell,重写setFrame: 方法即可 下面是具体代码实现: 步骤一 :

  • 万能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

  • RecyclerView的万能分割线

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

  • RecyclerView的使用之多种Item加载布局

    本文给大家介石介绍下如何利用RecyclerView实现多Item布局的加载,多Item布局的加载的意思就是在开发过程中List的每一项可能根据需求的不同会加载不同的Layout. 下面给大家展示下演示效果图: * 图片资源版权归属于Facebook dribbble RecyclerView实现加载不同的Layout的核心就是在Adapter的onCreateViewHolder里面去根据需求而加载不同的布局. 具体的实现步骤:(以Android Studio作为开发工具) 1:Gradle配

  • 详解Android中ListView实现图文并列并且自定义分割线(完善仿微信APP)

    昨天的(今天凌晨)的博文<Android中Fragment和ViewPager那点事儿>中,我们通过使用Fragment和ViewPager模仿实现了微信的布局框架.今天我们来通过使用ListView实现其中联系人一栏的基本视图,效果如下: 要实现上图的效果,我们要用到两个知识点: 1.这里我们使用自定义适配实现图文列表(当然也可以用SimpleAdapter) 通过继承BaseAdapter(抽象类)自定义适配器可以实现更灵活更复杂的列表. 自定义适配器ListView的优化: (1)使用固

  • Android中使用RecyclerView实现下拉刷新和上拉加载

    推荐阅读:使用RecyclerView添加Header和Footer的方法                       RecyclerView的使用之HelloWorld RecyclerView 是Android L版本中新添加的一个用来取代ListView的SDK,它的灵活性与可替代性比listview更好.本文给大家介绍如何为RecyclerView添加下拉刷新和上拉加载,过去在ListView当中添加下拉刷新和上拉加载是非常方便的利用addHeaderView和addFooterVie

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

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

  • android利用xml实现分割线

    因为没有美工, 所以只能自己动手了. 在layout文件夹里的xml 写 方法1:在layout里面的布局xml 文件里加上面的代码 <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/orange_normal" /> 效果图 在drawable文件夹里用 shape line 或 recta

随机推荐