timeline,一个简单精美的自定义时间轴
来源:互联网 发布:珠江钢琴天猫淘宝 编辑:程序博客网 时间:2024/06/05 20:57
H-Express Library——–timeline
这是母项目 H-Express 中的那个自定义时间轴view,现抽取出来分享给大家,这个自定义view比较简单,作为学习自定义view入门的朋友可不能错过了。
一般可以应用在单号追踪、历史事件记录、任务完成度显示等方面,作为Recyclerview或者listview的item布局即可。
先上图:
左边为H-Express中的效果,右边为原始效果,横向和竖向。
import
AS:
dependencies { compile 'com.qht1003077897.timeline:timelinelibrary:0.1' }
EC:
使用eclipse的同学直接到项目的github地址下面timelinelibrary中拷贝出两个类,一个attrs出来,放到自己项目中即可。
使用
<com.bt.mylibrary.TimeLineMarkerView android:id="@+id/time1" android:layout_width="150dp" android:layout_height="100dp" android:paddingTop="20dp" app:beginLine="@color/blue_sky" app:endLine="@color/blue_sky" app:oritation="true" app:marker="@drawable/timeline_bg_blue"/>
看完了怎么用下来就该看看源码实现了
timeline的实现很简单,我这里以竖向为例,横向的类似。总结为2点:
- 首先以整个view的正中心然后靠左边界为基准绘制中间的圆,如图。为什么要靠左边呢,因为放在左边界再加上合适的paddingLeft就很容易能控制圆的位置了(同理,横向的靠上边,使用paddingTop控制圆的位置)。
然后以这个圆为基准,再绘制上面的线条和下面的线条。
下面是6个属性,以供xml中进行设置。
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="TimeLineMarker"> <!--圆点大小--> <attr name="markerSize" format="dimension" /> <!--圆点颜色或者图片--> <attr name="marker" format="color|reference" /> <!--上面/左边线段颜色或者图片--> <attr name="beginLine" format="color|reference" /> <!--下面/右边线段颜色或者图片--> <attr name="endLine" format="color|reference" /> <!--线段粗细--> <attr name="lineSize" format="dimension" /> <!--横向还是竖向--> <attr name="oritation" format="boolean" /> </declare-styleable></resources>
很简单的 onMeasure() 方法,如果你的自定义 view 没有什么特殊需求,直接把这个拿去用,通用版。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthSpecSize= MeasureSpec.getSize(widthMeasureSpec); int heightSpecSize= MeasureSpec.getSize(heightMeasureSpec); int widthSpecMode= MeasureSpec.getMode(widthMeasureSpec); int heightSpecMode= MeasureSpec.getMode(heightMeasureSpec); //判断横向还是竖向,true为横向 if(oritation){ if(widthSpecMode== MeasureSpec.AT_MOST && heightSpecMode== MeasureSpec.AT_MOST){ setMeasuredDimension(120,80);//针对wrap情况做处理 }else if(widthSpecMode== MeasureSpec.AT_MOST ){ setMeasuredDimension(120,heightSpecSize); }else if(heightSpecMode== MeasureSpec.AT_MOST ){ setMeasuredDimension(widthSpecSize,80); } }else{ if(widthSpecMode== MeasureSpec.AT_MOST && heightSpecMode== MeasureSpec.AT_MOST){ setMeasuredDimension(80,120);//针对wrap情况做处理 }else if(widthSpecMode== MeasureSpec.AT_MOST ){ setMeasuredDimension(80,heightSpecSize); }else if(heightSpecMode== MeasureSpec.AT_MOST ){ setMeasuredDimension(widthSpecSize,120); } } }
因为我们使用的元素为3个 drawable,是现成的 view,所以已经不需要在 ondraw()方法中进行绘制了,而更多的是调整每个 drawable 的位置,所以下面的方法写在 onSizeChanged() 中更合适。
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); initDrawableSize(); if (mBeginLine != null) { mBeginLine.draw(canvas); } if (mEndLine != null) { mEndLine.draw(canvas); } if (mMarkerDrawable != null) { mMarkerDrawable.draw(canvas); } }
主要看一下 initDrawableSize() 方法:
private void initDrawableSize() { int pLeft=getPaddingLeft(); int pRight=getPaddingRight(); int pTop=getPaddingTop(); int pBottom=getPaddingBottom(); int width=getWidth(); int height=getHeight(); int cWidth=width-pLeft-pRight; int cHeight=height-pTop-pBottom; Rect bounds; int mMarkerSizepx=ResourceUtil.dip2px(getContext(),mMarkerSize); int mLineSizepx=ResourceUtil.dip2px(getContext(),mLineSize); //以竖向为例if(mMarkerDrawable!=null){ int marksize= Math.min(Math.min(cWidth,cHeight), mMarkerSizepx); mMarkerDrawable.setBounds(pLeft,pTop+height/2-marksize/2,pLeft+marksize,pTop+height/2-marksize/2+marksize); bounds=mMarkerDrawable.getBounds(); }else{ bounds=new Rect(pLeft+mLineSizepx/2,pTop+height/2,pLeft+mLineSizepx/2,pTop+height/2); } int halfLine=mLineSizepx >> 1; int lineLeft=bounds.centerX()-halfLine; if(mBeginLine!=null){ mBeginLine.setBounds(lineLeft,0,lineLeft+mLineSizepx,bounds.top); } if(mEndLine!=null){mEndLine.setBounds(lineLeft,bounds.bottom,lineLeft+mLineSizepx,height); }}
先了解一下 setBounds() 方法:
这句话的意思是:为Drawable 指定一个矩形区域,在onDraw() 方法被调用时使用。
这个矩形区域参数要求:矩形左边距view左边界的距离,矩形上边距view上边界的距离,矩形右边距view左边界的距离,矩形下边距view上边界的距离。
首先设置 mMarkerDrawable 的 bounds,左边的距离为pleft,上下为中心位置,确定了这个 bounds 为基准位置之后,再去绘制上下线条。
如果 mMarkerDrawable 为空,即在 xml 中不要这个圆,那么我们此处是将它看做一个点,一个左边的距离为pleft,上下为中心位置的点,作为我们的基准点,然后再去绘制上下线条,最终绘制出来的即为一条线段。
对于上下线的绘制很简单,这里以上线条为例,线条上端紧挨view的顶端,下端紧挨这个bounds的顶部,线条的长度为 bounds 的顶端距离上边界的距离。线条长度和 bounds 挂上钩之后,我们如果在 xml 中设置 paddingTop ,则 bounds.top 变大,线条长度变长,圆相应的往下移动。bounds.top= pTop +(height/2-mMarkerSize/2)。
//下来提供几个方法。以供代码动态设置 public void setMarkerSize(int markerSize) { if (this.mMarkerSize != markerSize) { mMarkerSize = markerSize; invalidate(); } } public void setBeginLine(Drawable beginLine) { if (this.mBeginLine != beginLine) { this.mBeginLine = beginLine; if (mBeginLine != null) { mBeginLine.setCallback(this); } invalidate(); } } ·············
源码github地址:
https://github.com/qht1003077897/timeline
我的QQ: 1003077897
我的csdn:http://blog.csdn.net/u012534831
欢迎交流。
- timeline,一个简单精美的自定义时间轴
- timeline一个简单精美的自定义时间轴
- 自定义一个简单精美的时间轴控件
- Android时间轴(Timeline)效果的实现
- Android TimeLine 时间节点轴的实现
- Timeline可展开的时间轴ExpandableListView
- Timeline时间轴
- Android开发时间轴 TimeLine
- 使用JavaFX时间轴(Timeline)编写的等待动画
- 针对时间轴TimeLine的一些js操作
- Android时间轴(Timeline)效果的实现(使用RecyclerView)
- 自定义控件-精美的心电图
- jQuery制作Facebook Timeline(时间轴)
- Android自定义简单时间轴的实现
- Day 23:使用 TimelineJS 构建精美的时间轴
- echarts通过timeline时间轴改变图表的数据,解决X轴,series问题
- 一个简单的时间轴实现
- 【时间轴】推荐几款jQuery时间轴插件Timeline
- 自定义标签,方便你复习
- 场景Scene
- AirBook GTI电脑这么厉害,竟然有数据恢复的功能?
- div下js失效的问题
- VC++:创建,调用Win32动态链接库
- timeline,一个简单精美的自定义时间轴
- 定时器
- 前端基于vue的分页
- Centos 7 右上角面板里没有wired network图标的问题
- linux下的python
- 实现UISearchBar的Placeholder居左显示
- 提高工作效率的几个chrome插件
- React简介
- PHP中COOKIE及时生效,不用刷新就可以使用