Android自定义View——动态进度条
这个是看了梁肖的demo,根据他的思路自己写了一个,但是我写的这个貌似计算还是有些问题,这个过程还是有点曲折的,不过还是觉得收获挺多的。比如通动画来进行动态的展示(之前做的都是通过Handler进行更新的所以现在换一种思路觉得特别好),还有圆弧的起止角度,矩形区域的计算等!关于绘制我们可以循序渐进,比如最开始先画圆,然后再画周围的线,最后设置动画部分就可以了。不多说了,上代码了。
代码
自定义View
publicclassColorProgressBarextendsView{
//下面这两行在本demo中没什么用,只是前几天看别人的代码时学到的按一定尺寸,设置其他尺寸的方式,自动忽略或者学习一下也不错
//privateintdefaultStepIndicatorNum=(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,40,getResources().getDisplayMetrics());
//intmCircleRadius=0.28fdefaultStepIndicatorNum;
//布局的宽高
privateintmWidth;
privateintmHeight;
//底层圆画笔
privatePaintmPaintbg;
//顶层圆的画笔
privatePaintmPaintft;
//周围线的画笔
privatePaintmPaintLine;
//外层线条的长度
privateintmLongItem=dip2px(20);
//线条与圆的间距
privateintmDistanceItem=dip2px(10);
//进度条的最大宽度(取底层进度条与顶层进度条宽度最大的)
privateintmProgressWidth;
//底层圆的颜色
privateintmBackColor;
//顶层圆的颜色
privateintmFrontColor;
//底层圆、顶层圆的宽度
privatefloatmBackWidth;
privatefloatmFrontWidth;
//设置进度
privatefloatcurrentvalue;
//通过动画演示进度
privateValueAnimatoranimator;
privateintcurvalue;
publicColorProgressBar(Contextcontext){
this(context,null,0);
}
publicColorProgressBar(Contextcontext,AttributeSetattrs){
this(context,attrs,0);
}
publicColorProgressBar(Contextcontext,AttributeSetattrs,intdefStyleAttr){
super(context,attrs,defStyleAttr);
TypedArrayta=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();
}
/
都是画笔初始化
/
privatevoidinit(){
mPaintbg=newPaint(Paint.ANTI_ALIAS_FLAG);
mPaintbg.setStrokeWidth(mProgressWidth);
mPaintbg.setColor(mBackColor);
mPaintbg.setStrokeCap(Paint.Cap.ROUND);
mPaintbg.setStyle(Paint.Style.STROKE);
mPaintft=newPaint(Paint.ANTI_ALIAS_FLAG);
mPaintft.setColor(mFrontColor);
mPaintft.setStyle(Paint.Style.STROKE);
mPaintft.setStrokeWidth(mFrontWidth);
mPaintft.setStrokeCap(Paint.Cap.ROUND);
mPaintLine=newPaint(Paint.ANTI_ALIAS_FLAG);
mPaintLine.setColor(Color.BLACK);
mPaintLine.setStrokeWidth(5);
}
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
mWidth=mHeight=getScreenWidth()2/3;
setMeasuredDimension(mWidth,mHeight);
}
@Override
protectedvoidonDraw(Canvascanvas){
super.onDraw(canvas);
//绘制底层圆弧,矩形的具体计算见图片
canvas.drawArc(newRectF(mProgressWidth+mDistanceItem+mLongItem,mProgressWidth+mDistanceItem+mLongItem,mWidth-mProgressWidth-mDistanceItem-mLongItem,mHeight-mProgressWidth-mDistanceItem-mLongItem),0,360,true,mPaintbg);
//绘制边缘线
canvas.save();
canvas.rotate(144,mWidth/2,mHeight/2);
for(inti=0;i<=30;i++){
canvas.rotate(-9,mWidth/2,mHeight/2);
if(i%5==0){
canvas.drawLine(mWidth/2,10,mWidth/2,mLongItem,mPaintbg);
}else{
canvas.drawLine(mWidth/2,25,mWidth/2,mLongItem,mPaintLine);
}
}
canvas.restore();
//给画笔设置渐变
SweepGradientsweepGradient=newSweepGradient(mWidth/2,mHeight/2,Color.RED,Color.YELLOW);
mPaintft.setShader(sweepGradient);
//绘制顶层圆弧,currentvalue在改变时呈现动态效果
canvas.drawArc(newRectF(mProgressWidth+mDistanceItem+mLongItem,mProgressWidth+mDistanceItem+mLongItem,mWidth-mProgressWidth-mDistanceItem-mLongItem,mHeight-mProgressWidth-mDistanceItem-mLongItem),135,currenwww.tt951.comtvalue,false,mPaintft);
mPaintft.setTextSize(100);
mPaintft.setTextAlign(Paint.Align.CENTER);
//绘制文本
canvas.drawText(String.format("%.0f",currentvalue),mWidth/2,mHeight/2+50,mPaintft);
}
/
设置动画
@paramvalue
/
publicvoidsetCurrentValue(floatvalue){
//currentvalue=value;
animator=ValueAnimator.ofFloat(currentvalue,value);
animator.setDuration(3000);
animator.setTarget(currentvalue);
animator.addUpdateListener(newValueAnimator.AnimatorUpdateListener(){
@Override
publicvoidonAnimationUpdate(ValueAnimatorvalueAnimator){
currentvalue=(float)valueAnimator.getAnimatedValue();
curvalue=curvalue/10;
invalidate();
}
});
animator.start();
}
privateintdip2px(floatdip){
floatdensity=getContext().getResources().getDisplayMetrics().density;
return(int)(dipdensity+0.5f);
}
}
privateintgetScreenWidth(){
WindowManagermanager=(WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
Displaydisplay=manager.getDefaultDisplay();
if(Build.VERSION.SDK_INT>=13){
Pointpoint=newPoint();
display.getSize(point);
returnpoint.x;
}else{
returndisplay.getWidth();
}
}
矩形计算
这里写图片描述
Activity调用
@Override
protectedvoidonCreate(@NullableBundlesavedInstanceState){
super.onCreate(savewww.baiyuewang.netdInstanceState);
setContentView(R.layout.colorprogressbar);
mBtStart1=(Button)findViewById(R.id.bt1);
bar1=(ColorProgressBar)findViewById(R.id.cp1);
mBtStart1.setOnClickListener(newView.OnClickListener(){
@Override
publicvoidonClick(Viewview){
bar1.setCurrentValue(270);
}
});
}
自定义属性
布局
注意:为了使用自定义属性需要添加一行代码(AS)
xmlns:app="http://schemas.android.com/apk/res-auto"
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">
|
|