RecycleView自定义ItemDecoration,实现时间轴效果

来源:互联网 发布:乔任梁网络暴力图片 编辑:程序博客网 时间:2024/05/28 04:55

最近进行知识点扫盲,关于RecycleView的进行整理,自定义ItemDecoration,实现时间轴效果,先上图:

这里写图片描述

此文参考了Carson_Ho的博客:http://www.jianshu.com/p/9a796bb23a47,在此特别感谢,感觉怎么写都没有大神写的好,但是还要自己记录一下,嘿嘿。
时间轴是通过自定义ItemDecoration实现的,接下来我们分析一下ItemDecoration其内部的方法,
一、getItemOffsets
作用:设置ItemView的内嵌的偏移长度
其实在ItemView外部包含一层矩形,该方法就是决定其left,top,right,bottom的长度,完整方法如下:

@Override    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {        super.getItemOffsets(outRect, view, parent, state);        // 参数说明:        // 1. outRect:全为 0 的 Rect(包括着Item)        // 2. view:RecyclerView 中的 视图Item        // 3. parent:RecyclerView 本身        // 4. state:状态        outRect.set(50, 0, 0,50);        // 4个参数分别对应左(Left)、上(Top)、右(Right)、下(Bottom)        // 上述语句代表:左&下偏移长度=50px,右 & 上 偏移长度 = 0        //具体过程:在RecyclerView进行子View宽高测量时(measureChild()),        // 会将getItemOffsets()里设置的 outRect4个属性值(Top、Bottom、Left、Right)通过insert值累加 ,并最终添加到子View的 Padding属性中    }

二、onDraw
作用:顾名思义,用来绘制的,类似view的ondraw()方法,此处注意的是当ItemDecoration的ondraw与child view有重叠的区域,最终会显示child的视图,因为ItemDecoration先绘制子的itemView后绘制,此现象称为onDraw()的 OverDraw。此方法一般配合上面的getItemOffsets,先给预留出空间,然后在此空间进行绘制,完整方法如下:

    //参数说明    // 1、c  画布    //2、parent Recycle本身    //3、state 状态   //通过此方法我们可以绘制想要绘制的图案、图片等      @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        super.onDraw(c, parent, state);    }

三、onDrawOver
作用:与上面的onDraw方法类似,唯一不同的是当ItemDecoration的ondraw与child view有重叠的区域,最终会显示ItemDecoration的ondrawOver绘制的视图,完整方法如下:

@Override    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {        super.onDrawOver(c, parent, state);    }

四、思路分析
通过上面的几个方法我们完全可以自定义任何分割线了,然后分析时光轴,如下(借鉴):
这里写图片描述

1、首先设置便宜长度,预留空间,
2、绘制时光轴
3、绘制时间文本,下面分别实现

1、首先设置偏移长度,预留空间,如下

//首先通过getItemOffsets方法设置相应的偏移量    @Override    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {        super.getItemOffsets(outRect, view, parent, state);        // 设置ItemView的左 & 上偏移长度分别为200 px & 50px,即此为onDraw()可绘制的区域        outRect.set(itemView_leftinterval, itemView_topinterval, 0, 0);    }

2、绘制时光轴及文本都在onDraw()内实现,如下:

// 重写onDraw()    // 作用:在间隔区域里绘制时光轴线 & 时间文本    @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        super.onDraw(c, parent, state);        //获取子view的数量        int count  =parent.getChildCount();        //循环遍历,分别获取它们的位置信息,然后再绘制对应的分割线        for (int i = 0; i <count ; i++) {            // 获取每个Item对象            View child = parent.getChildAt(i);            /**             * 绘制图标             */            //自定义设置图标位置            float centerx = child.getLeft() - itemView_leftinterval / 3;            float centery = child.getTop() - itemView_topinterval + (itemView_topinterval + child.getHeight()) / 2;            // 通过Canvas绘制角标             c.drawBitmap(mIcon,centerx - circle_radius ,centery - circle_radius,mPaint);            /**             * 绘制上半轴线             */            // 上端点坐标(x,y)            float upLine_up_x = centerx+circle_radius;            float upLine_up_y = child.getTop() - itemView_topinterval;            // 下端点坐标(x,y)            float upLine_bottom_x = centerx+circle_radius;            float upLine_bottom_y = centery - circle_radius;            //绘制上半部轴线            c.drawLine(upLine_up_x, upLine_up_y, upLine_bottom_x, upLine_bottom_y, mPaint);            /**             * 绘制下半轴线             */            // 上端点坐标(x,y)            float bottomLine_up_x = centerx+circle_radius;            float bottom_up_y = centery + circle_radius;            // 下端点坐标(x,y)            float bottomLine_bottom_x = centerx+circle_radius;            float bottomLine_bottom_y = child.getBottom();            //绘制下半部轴线            c.drawLine(bottomLine_up_x, bottom_up_y, bottomLine_bottom_x, bottomLine_bottom_y, mPaint);            /**             * 绘制左边时间文本             */            // 获取每个Item的位置            int index = parent.getChildAdapterPosition(child);            // 设置文本起始坐标            float Text_x = child.getLeft() - itemView_leftinterval * 5 / 6;            float Text_y = upLine_bottom_y;            // 根据Item位置设置时间文本            for (int j = 0; j <timedata.size() ; j++) {                if (index==j){                    c.drawText((String)timedata.get(j).get("time"), Text_x, Text_y, mPaint1);                    c.drawText((String)timedata.get(j).get("year"), Text_x + 5, Text_y + 20, mPaint2);                }            }        }    }

4,、在Activity中的使用

// times时间轴右边的时间数据,bitmap是中间的图片    ry_time.addItemDecoration(new TimezItemdecor(BitmapFactory.decodeResource(getResources(),R.mipmap.earnings),listItem));

5、最终效果:
这里写图片描述

总结;当我们知道ItemDecoration内部的三个方法用途之后,我们完全可以自己定义出各种更炫的效果,在此特别感谢Carson_Ho大神 http://www.jianshu.com/p/9a796bb23a47,缜密的思维,清晰的流程图,化繁为简,持续学习中。感谢生活,感谢科技,感谢分享!
五、源码地址
http://download.csdn.net/download/ali18510953445/9988209

阅读全文
0 0
原创粉丝点击