解决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());
    }
  }
}

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

你可能感兴趣的:(解决RecycleView分割线不居中的三种方法)