android自定义控件实现简易时间轴(2)
程序员文章站
2022-03-02 15:21:19
这篇做了一个简单的时间轴控件。右侧的数据就是一个简单的字符串。问题还是有的,当右侧的文字长度不一样的时候就会有问题了。现在可以修改一下适配右侧的文字。效果如下:代码:private paint bgp...
这篇做了一个简单的时间轴控件。右侧的数据就是一个简单的字符串。问题还是有的,当右侧的文字长度不一样的时候就会有问题了。现在可以修改一下适配右侧的文字。
效果如下:
代码:
private paint bgpaint, linepaint, borderpaint,textpaint; private rect bgrect, textrect; //基本属性 private int mtextsize; private int mtextcolor; private string mtexttitle="默认文本内容"; private int linecolr = color.parsecolor("#aaaaaa"); private int bordercolor = color.parsecolor("#aaaaaa"); private int bgcolor = color.parsecolor("#138ddd"); private int mbordercolor=0xffdddddd; private int mborderwidth = 10; private int mlinecolor=color.parsecolor("#ff000000"); private int mlinewidth = 2; private int mlineheight; private int mbgcolor; private int mwidth =0; private int mheight =300;//整个控件的宽和高 //line绘制 private int linelocation = -1;//0 上方 1 下方 2 上下两个 private int mradius = 90;//直径,最终会被宽高限制 //设置line的位置 0 上方 1 下方 2 上下两个 public void setlinelocation(int linelocation) { this.linelocation = linelocation; } //设置纯色的整圆形,包括背景 public void setbgandbordercolor(int color) { this.mbgcolor = color; } public void setmheight(int mheight) { this.mheight = mheight; } public void setmbordercolor(int mbordercolor) { this.mbordercolor = mbordercolor; } public void setmtexttitle(string mtexttitle) { this.mtexttitle = mtexttitle; } public void setmradius(int mradius) { this.mradius = mradius; } public void setmlineheight(int mlineheight) { this.mlineheight = mlineheight; } public timelinesingleview(context context) { this(context,null); } public timelinesingleview(context context, attributeset attrs) { this(context, attrs,0); } public timelinesingleview(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); typedarray a = context.gettheme().obtainstyledattributes(attrs, r.styleable.customcicleview, defstyleattr, 0); int n = a.getindexcount(); for (int i = 0; i < n; i++) { int attr = a.getindex(i); switch (attr) { case r.styleable.customcicleview_textsize: // 默认设置为16sp,typevalue也可以把sp转化为px mtextsize = a.getdimensionpixelsize(attr, (int) typedvalue.applydimension( typedvalue.complex_unit_dip, 14, getresources().getdisplaymetrics())); break; case r.styleable.customcicleview_textcolor: mtextcolor = a.getcolor(attr, color.black); break; case r.styleable.customcicleview_texttitle: mtexttitle = a.getstring(attr); break; case r.styleable.customcicleview_linewidth: mlinewidth = a.getdimensionpixelsize(attr, (int) typedvalue.applydimension( typedvalue.complex_unit_dip, 2, getresources().getdisplaymetrics())); break; case r.styleable.customcicleview_linecolor: mlinecolor = a.getcolor(attr, linecolr); break; case r.styleable.customcicleview_mradius: mradius=a.getdimensionpixelsize(attr, (int) typedvalue.applydimension( typedvalue.complex_unit_dip, 100, getresources().getdisplaymetrics())); break; case r.styleable.customcicleview_borderwidth: mborderwidth = a.getdimensionpixelsize(attr, (int) typedvalue.applydimension( typedvalue.complex_unit_dip, 10, getresources().getdisplaymetrics())); break; case r.styleable.customcicleview_bordercolor: mbordercolor = a.getcolor(attr, bordercolor); break; case r.styleable.customcicleview_bgcolor: mbgcolor = a.getcolor(attr, bgcolor); break; } } a.recycle(); bgpaint = new paint(); borderpaint = new paint(); linepaint = new paint(); textpaint = new paint(); textrect = new rect(); textpaint.settextsize(mtextsize); } //exactly :在准确的数值和match_parent的状态是这个值 列表中,wrap_content的状态下必须计算一个合适的值 @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { super.onmeasure(widthmeasurespec, heightmeasurespec); int w = 0; int h =0; int widthmode=measurespec.getmode(widthmeasurespec); int heightmode=measurespec.getmode(heightmeasurespec); int widthsize = measurespec.getsize(widthmeasurespec); int heightsize = measurespec.getsize(heightmeasurespec); if(widthmode==measurespec.exactly){ w=widthsize; }else{ w=math.max(mheight,mradius+getpaddingright()+getpaddingleft()); } if(heightmode==measurespec.exactly){ h=heightsize; }else{ h=math.max(mheight,mradius+getpaddingtop()+getpaddingbottom()); } setmeasureddimension(w,h); } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); int centrex = getwidth()/ 2; // 获取圆心的x坐标 int centrey=getheight()/2; //半径比较 mborderwidth =(mborderwidth>=mradius/10)?(mradius/10):mborderwidth;//半径的1/5 int radius = mradius/2 - mborderwidth / 2;// 半径 if(mlineheight<=0){ mlineheight=math.abs(getheight()/2-radius);//这个地方要判断设置正负 } //绘制圆 bgpaint.setantialias(true); // 消除锯齿 bgpaint.setcolor(mbgcolor); bgpaint.setstyle(paint.style.fill); // 设置实心 canvas.drawcircle(centrex, centrey, radius, bgpaint); //绘制圆环 borderpaint.setstrokewidth(mborderwidth); // 设置圆环的宽度 borderpaint.setantialias(true); // 消除锯齿 if (mbordercolor != 0) { borderpaint.setcolor(mbordercolor); } else { borderpaint.setcolor(bordercolor); } borderpaint.setstyle(paint.style.stroke); // 设置实心 canvas.drawcircle(centrex,centrey, radius - mborderwidth / 2+mlinewidth/2, borderpaint); //绘制文本 textpaint.settextsize(mtextsize); textpaint.setcolor(mtextcolor); textpaint.gettextbounds(mtexttitle, 0, mtexttitle.length(), textrect); canvas.drawtext(mtexttitle, centrex -textrect.width()/2-mborderwidth/2, centrey + textrect.height() / 2, textpaint); //绘制线条 drawlineall(canvas,centrex,centrey,radius); } //上下都绘制不用 //1 上方 0 下方 2 上下两个 private void drawlineall(canvas canvas, float centrex, float centrey,int radius) { if(linelocation==-1){ linepaint.setcolor(bordercolor); linepaint.setstrokewidth(mlinewidth); canvas.drawline(centrex, 0, centrex, centrey-radius, linepaint);//上方的 canvas.drawline(centrex, centrey+radius, centrex, getheight(), linepaint);//下方的 }else{ //这个可以绘制不同的line linepaint.setcolor(linecolr); linepaint.setstrokewidth(mlinewidth); if (linelocation == 0) { canvas.drawline(centrex, centrey+radius, centrex, getheight(), linepaint); } else if (linelocation == 1) { canvas.drawline(centrex, 0, centrex, centrey -radius , linepaint); } else if (linelocation == 2) { canvas.drawline(centrex, centrey+radius, centrex, getheight(), linepaint); canvas.drawline(centrex, 0, centrex, centrey -radius , linepaint); } } }
其他代码和之前文章一样就不贴了,但是还有一个问题就是,这个控件是放在一个列表里面的,你在适配器中使用的时候布局要是wrap的状态下要计算一个合适的高度,比如listview 的item的高度。这里我没有实现,还是在match和固定高度中,后期更改。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。