Android view自定义实现动态进度条
程序员文章站
2024-02-24 23:50:52
android 自定义view实现动态进度条
效果图:
这个是看了梁肖的demo,根据他的思路自己写了一个,但是我写的这个貌似计算还是有些问题,从...
android 自定义view实现动态进度条
效果图:
这个是看了梁肖的demo,根据他的思路自己写了一个,但是我写的这个貌似计算还是有些问题,从上面的图就可以看出来,左侧、顶部、右侧的线会有被截掉的部分,有懂得希望能给说一下,改进一下,这个过程还是有点曲折的,不过还是觉得收获挺多的。比如通动画来进行动态的展示(之前做的都是通过handler进行更新的所以现在换一种思路觉得特别好),还有圆弧的起止角度,矩形区域的计算等!关于绘制我们可以循序渐进,比如最开始先画圆,然后再画周围的线,最后设置动画部分就可以了。不多说了,上代码了。
代码
自定义view
public class colorprogressbar extends view{ //下面这两行在本demo中没什么用,只是前几天看别人的代码时学到的按一定尺寸,设置其他尺寸的方式,自动忽略或者学习一下也不错 // private int defaultstepindicatornum= (int) typedvalue.applydimension(typedvalue.complex_unit_dip,40,getresources().getdisplaymetrics()); // int mcircleradius=0.28f*defaultstepindicatornum; //布局的宽高 private int mwidth; private int mheight; //直径 private int mdiameter=500; //底层圆画笔 private paint mpaintbg; //顶层圆的画笔 private paint mpaintft; //周围线的画笔 private paint mpaintline; //外层线条的长度 private int mlongitem=dip2px(20); //线条与圆的间距 private int mdistanceitem=dip2px(10); //进度条的最大宽度(取底层进度条与顶层进度条宽度最大的) private int mprogresswidth; //底层圆的颜色 private int mbackcolor; //顶层圆的颜色 private int mfrontcolor; //底层圆、顶层圆的宽度 private float mbackwidth; private float mfrontwidth; //设置进度 private float currentvalue; //通过动画演示进度 private valueanimator animator; private int curvalue; public colorprogressbar(context context) { this(context,null,0); } public colorprogressbar(context context, attributeset attrs) { this(context, attrs,0); } public colorprogressbar(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); typedarray ta=context.obtainstyledattributes(attrs, r.styleable.colorprogressbar); mbackcolor= ta.getcolor(r.styleable.colorprogressbar_back_color, color.black); mfrontcolor=ta.getcolor(r.styleable.colorprogressbar_front_color,mbackcolor); mbackwidth=ta.getdimension(r.styleable.colorprogressbar_back_width,dip2px(10)); mfrontwidth=ta.getdimension(r.styleable.colorprogressbar_front_width,dip2px(10)); mprogresswidth=mbackwidth>mfrontwidth?(int)mbackwidth:(int)mfrontwidth; //注意释放资源 ta.recycle(); init(); } /** * 都是画笔初始化 */ private void init() { mpaintbg=new paint(paint.anti_alias_flag); mpaintbg.setstrokewidth(mprogresswidth); mpaintbg.setcolor(mbackcolor); mpaintbg.setstrokecap(paint.cap.round); mpaintbg.setstyle(paint.style.stroke); mpaintft=new paint(paint.anti_alias_flag); mpaintft.setcolor(mfrontcolor); mpaintft.setstyle(paint.style.stroke); mpaintft.setstrokewidth(mfrontwidth); mpaintft.setstrokecap(paint.cap.round); mpaintline=new paint(paint.anti_alias_flag); mpaintline.setcolor(color.black); mpaintline.setstrokewidth(5); } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { super.onmeasure(widthmeasurespec, heightmeasurespec); // 宽度=高度=(长指针+指针与圆盘的间距+进度条的粗细+半径)*2 log.e("测量数据","longitem:"+mlongitem+"mdistanceitem:"+mdistanceitem+"mprogresswidth:"+mprogresswidth+"mdiameter:"+mdiameter/2); mwidth=(int)2*(mlongitem+mdistanceitem+mprogresswidth*2+mdiameter/2); mheight=(int)2*(mlongitem+mdistanceitem+mprogresswidth*2+mdiameter/2); log.e("自定义view","高度"+mheight+"宽度"+mwidth); setmeasureddimension(mwidth,mheight); } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); //绘制底层圆弧,矩形的具体计算见图片 canvas.drawarc(new rectf(mprogresswidth/2+mdistanceitem+mlongitem,mprogresswidth/2+mdistanceitem+mlongitem,mwidth-mprogresswidth/2-mdistanceitem-mlongitem,mheight-mprogresswidth/2-mdistanceitem-mlongitem),0,360,true,mpaintbg); // sweepgradient gradient=new sweepgradient(); //绘制边缘线 canvas.save(); canvas.rotate(144,mwidth/2,mheight/2); for(int i=0;i<=30;i++){ canvas.rotate(-9,mwidth/2,mheight/2); if(i%5==0){ canvas.drawline(mwidth/2,5,mwidth/2,mlongitem,mpaintbg); }else { canvas.drawline(mwidth/2,25,mwidth/2,mlongitem,mpaintline); } } canvas.restore(); //给画笔设置渐变 sweepgradient sweepgradient=new sweepgradient(mwidth/2,mheight/2,color.red,color.yellow); mpaintft.setshader(sweepgradient); //绘制顶层圆弧,currentvalue在改变时呈现动态效果 canvas.drawarc(new rectf(mprogresswidth/2+mdistanceitem+mlongitem,mprogresswidth/2+mdistanceitem+mlongitem,mwidth-mprogresswidth/2-mdistanceitem-mlongitem,mheight-mprogresswidth/2-mdistanceitem-mlongitem),135,currentvalue,false,mpaintft); mpaintft.settextsize(100); mpaintft.settextalign(paint.align.center); //绘制文本 canvas.drawtext(string.format("%.0f",currentvalue),mwidth/2,mheight/2+50,mpaintft); invalidate(); } /** * 设置动画 * @param value */ public void setcurrentvalue(float value){ // currentvalue=value; animator=valueanimator.offloat(currentvalue,value); animator.setduration(3000); animator.settarget(currentvalue); animator.addupdatelistener(new valueanimator.animatorupdatelistener() { @override public void onanimationupdate(valueanimator valueanimator) { currentvalue= (float) valueanimator.getanimatedvalue(); curvalue=curvalue/10; } }); animator.start(); } private int dip2px(float dip){ float density=getcontext().getresources().getdisplaymetrics().density; return (int)(dip*density+0.5f); } }
矩形计算
activity调用
@override protected void oncreate(@nullable bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.colorprogressbar); mbtstart1= (button) findviewbyid(r.id.bt1); bar1= (colorprogressbar) findviewbyid(r.id.cp1); mbtstart1.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { bar1.setcurrentvalue(270); } }); }
自定义属性
<declare-styleable name="colorprogressbar"> <attr name="back_color" format="color"></attr> <attr name="front_color" format="color"></attr> <attr name="back_width" format="dimension"></attr> <attr name="front_width" format="dimension"></attr> </declare-styleable>
布局
注意:为了使用自定义属性需要添加一行代码(as)
xmlns:app=http://schemas.android.com/apk/res-auto
布局
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <button android:id="@+id/bt1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="start1"/> <com.demo.demo.networkdemo.colorprogressbar.widget.colorprogressbar android:id="@+id/cp1" android:layout_width="232dp" android:layout_height="match_parent" android:layout_gravity="center_horizontal" app:back_color="@color/colorprimary" app:front_color="@color/coloraccent" android:background="@mipmap/ic_launcher"/> </linearlayout>
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
推荐阅读