配色: 字号:
Android 自定义View——动态进度条
2016-12-21 | 阅:  转:  |  分享 
  
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">


android:id="@+id/bt1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="start1"/>




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"/>







献花(0)
+1
(本文系thedust79首藏)