当前位置: 首页 > 编程笔记 >

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

陶淳
2023-03-14
本文向大家介绍解决RecycleView分割线不居中的三种方法,包括了解决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());
    }
  }
}

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

 类似资料:
  • 本文向大家介绍详解JavaScript中分解数字的三种方法,包括了详解JavaScript中分解数字的三种方法的使用技巧和注意事项,需要的朋友参考一下 本文基于免费代码营基本算法脚本“分解数字” 在数学中,非负整数n的阶乘可能是一个棘手的算法。在本文中,我将解释这种方法,首先使用递归函数,第二种使用而循环,第三种使用以循环。 算法挑战 返回提供的整体的阶乘。 如果整体用字母n表示,则阶乘是所有小于

  • 本文向大家介绍VBS中解决带空格路径的三种方法,包括了VBS中解决带空格路径的三种方法的使用技巧和注意事项,需要的朋友参考一下 方法一: 方法二: 方法三:

  • 本文向大家介绍angular.js中解决跨域问题的三种方式,包括了angular.js中解决跨域问题的三种方式的使用技巧和注意事项,需要的朋友参考一下 前言 开始本文之前,大家应该首先了解,协议、主机名和端口号相同叫同源。同源策略允许页面从同一个站点加载和执行特定的脚本。站外其他来源的脚本同页面的交互则被严格限制。 要解决这个问题就需要跨域,本文介绍解决angular中的跨域的三种方式: 一、JS

  • 本文向大家介绍Java线程三种命名方法详解,包括了Java线程三种命名方法详解的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了Java线程三种命名方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.实例化一个线程对象 2.实例化一个线程对象的同时,通过构造方法对线程进行命名 3.使用自定义的线程类,在实例化线程对象的同时,进行

  • 本文向大家介绍解决layer.msg 不居中 ifram中的问题,包括了解决layer.msg 不居中 ifram中的问题的使用技巧和注意事项,需要的朋友参考一下 在ifram中layer.alert 只展示当前页面 如何让弹框在整个页面中展示 而不是在ifram中 本以为这样就可以 在主页面中还需要引入layer 否则总是提示parent.layer.open()总是提示TypeError: p

  • 介绍 用于将内容分隔为多个区域。 引入 import { createApp } from 'vue'; import { Divider } from 'vant'; const app = createApp(); app.use(Divider); 代码演示 基础用法 默认渲染一条水平分割线。 <van-divider /> 展示文字 通过插槽在可以分割线中间插入内容。 <van-di