android 动态进度条,Android view自定义实现动态进度条_Android_脚本之家

Android  自定义view实现动态进度条

效果图:

84276f42397fa2dfe16b95ab66bd199e.gif

这个是看了梁肖的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);

}

}

矩形计算

85b2fde4a91a6b62107d78b389d31fe9.png

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);

}

});

}

自定义属性

布局

注意:为了使用自定义属性需要添加一行代码(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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值