• RecycleView设置顶部分割线(记录一个坑)


    大家都知道,想给RecycleView设置分割线可以重写RecyclerView.ItemDecoration

    项目过程中,遇到一个需求:RecycleView顶部有一条灰色的间隔,我想到了给RecycleView设置分割线的方法,当然只给第一个Item设置,而且在上方。

    public class MyDividerItemDecoration extends RecyclerView.ItemDecoration {
    
        private Drawable mDivider;
    
        /**
         * Custom divider will be used
         */
        public MyDividerItemDecoration(Context context, int resId) {
            mDivider = ContextCompat.getDrawable(context, resId);
        }
        public DividerItemDecoration(Drawable drawable) {
    mDivider = drawable;
    }
      @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, 
    RecyclerView.State state) {
    super.getItemOffsets(outRect, view, parent, state); RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); //因为绘制了顶部分割线,因此需要将第一行的item下移相应的距离
    //这里要注意,判断该RecycleView是什么布局,如果是竖直方向上的线性布局(水平方向上的这里没有考虑)
    //,那么需要让第一个Item下移,移动的距离是分割线的高度,因为分割线会占据Item的空间
    //如果是网格布局,那么需要把第一行的所有Item都下移相应的高度
    if (layoutManager instanceof LinearLayoutManager) { if (parent.getChildAdapterPosition(view) == 0) { outRect.set(0, mDivider.getIntrinsicHeight(), 0, 0); } } if (layoutManager instanceof GridLayoutManager) { if (parent.getChildAdapterPosition(view) >= 0 &&
    parent.getChildAdapterPosition(view) < getSpanCount(parent)) { outRect.set(0, mDivider.getIntrinsicHeight(), 0, 0); } } } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { //绘制分割线 int left = 0; int right = parent.getWidth(); View child = parent.getChildAt(0); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); //不可以直接设置top = 0;因为这样的话分隔线就不会跟着移动,因为top = 0,是绝对位置,
    //所以应该设置为子view的相对位置
    //这样才可以跟着滑动。
    //child的顶部坐标,减去设置的margin_top的值,再减去child为了给分割线腾出空间所下滑的高度,
    //这样分割线才会在顶部
    int top = child.getTop() - params.topMargin - mDivider.getIntrinsicHeight(); int bottom; bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } 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(); } else if (layoutManager instanceof LinearLayoutManager) { spanCount = layoutManager.getItemCount(); } return spanCount; }

    在onDrawOver方法中可以绘制分割线。

    这里有一个需要注意的坑,调试了很久,最终才发现,难受。

    在onDrawOver里面,一开始我设置top = 0;因为绘制在顶部嘛。结果出现了一个现象,顶部分割线一直停留在顶部,不会跟着移动。最后改为int top = child.getTop() - params.topMargin - mDivider.getIntrinsicHeight();才成功了。为什么呢?

    因为直接写top = 0;这是绝对位置了,要让分割线也跟着滑动,需要用的是相对位置,相对于item的位置,这样才能够跟着item滑动

    调用

    recyclerView.addItemDecoration(new MyDividerItemDecoration(this, R.drawable.item_decoration));

    item_decoration代码如下:

    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <size android:height="10dp" />
        <solid android:color="@color/comic_gray_bg" />
    </shape>

     

    或者我们可以直接代码中创建Drawable,然后传进去:

    //添加白色分割线在顶部
    GradientDrawable drawable = new GradientDrawable();
    drawable.setColor(ContextCompat.getColor(this, R.color.white));
    drawable.setShape(GradientDrawable.RECTANGLE);
    drawable.setSize(0, 3);
    recyclerView.addItemDecoration(new DividerItemDecoration(drawable));

    尊重劳动成果,转载请标明出处:https://www.cnblogs.com/tangZH/p/9489486.html 

    更多链接: http://77blogs.com/?p=569 

  • 相关阅读:
    Redis之String
    代码质量管理工具——SonarQube
    XML文件(2)--使用DOM4J示例
    XML文件(1)--使用DOM示例
    Maven之构件
    使用JS,获取URL中指定参数的值
    jQuery导入Eclipse后报错解决方法
    关于MySQL存储过程中遇到的一个错误
    学习MySQL之数据类型(四)
    jmeter直连数据库【转】
  • 原文地址:https://www.cnblogs.com/tangZH/p/9489486.html
Copyright © 2020-2023  润新知