android带动画的圆形进度条

偶然发现一个很好的app,圆环进度条,带加速动画,看起来相当不错。尝试着克隆一下。

反编译一看,哇塞,啥3.1415926都干出来了,太高端玩不转啊,算了,想想其它方式吧。

先看效果图:


这个草稿存了小半年.....先发布了再说。实现了预想的效果,具体代码稍后奉上。


代码:

package com.zkbc.finance.widget;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;

import com.zkbc.finance.R;


/**
 * 自定义进度
 *
 * @author Rock Lee
 * @date 2016年4月18日
 */
public class MyProgessLine extends View {

    //需要执行动画的参数名
    private static final String PROGRESS_PROPERTY = "progress";

    private Paint paint;// 画笔

    RectF rectF;

    private int bmColor;// 底部横线颜色
    private float bmHight;// 底部横线高度
    private int color;// 进度条颜色
    private float hight;// 进度条高度

    protected float progress;

    public void setColor(int color) {
        this.color = color;
    }

    public MyProgessLine(Context context) {
        this(context, null);
    }

    public MyProgessLine(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyProgessLine(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs);
        paint = new Paint();
        rectF = new RectF();

        TypedArray mTypedArray = context.getTheme().obtainStyledAttributes(
                attrs, R.styleable.MyProgressLine, defStyleAttr, 0);

        bmColor = mTypedArray.getColor(R.styleable.MyProgressLine_myProgressLine_bmColor,
                Color.GRAY);
        bmHight = mTypedArray
                .getDimension(R.styleable.MyProgressLine_myProgressLine_bmHight, 2);
        color = mTypedArray.getColor(R.styleable.MyProgressLine_myProgressLine_color,
                Color.BLUE);
        hight = mTypedArray.getDimension(R.styleable.MyProgressLine_myProgressLine_hight, 2);

    }

    @Override
    protected void onDraw(Canvas canvas) {

        paint.setColor(bmColor);
        paint.setStrokeCap(Paint.Cap.SQUARE);// 圆角
        // paint.setStyle(Paint.Style.FILL); // 设置实心
        paint.setStrokeWidth(bmHight); // 设置笔画的宽度
        paint.setAntiAlias(true); // 消除锯齿

        rectF.set(0, 0, getWidth(), bmHight);
        //canvas.drawRoundRect(rectF, bmHight / 2, bmHight / 2, paint);
        canvas.drawRect(0, 0, getWidth(), bmHight, paint);

        paint.setColor(color);
        paint.setStrokeWidth(hight); // 设置笔画的宽度

        rectF.set(0, 0, progress, bmHight);
        //矩形
//		canvas.drawRoundRect(rectF, hight / 2, hight / 2, paint);
        canvas.drawRect(0, 0, progress, bmHight, paint);

    }

    public float getProgress() {
        return progress;
    }

    public void setProgress(float progress) {
        this.progress = progress * getWidth() / 100;
        invalidate();
    }

    /**
     * 赋值+执行动画
     *
     * @param progressText 进度 float
     */
    public void dodo(float progressText) {
        AnimatorSet animation = new AnimatorSet();

        ObjectAnimator progressAnimation = ObjectAnimator.ofFloat(this, PROGRESS_PROPERTY,
                0f, progressText);
        progressAnimation.setDuration(1000);//动画耗时
        progressAnimation.setInterpolator(new AccelerateDecelerateInterpolator());

        animation.playTogether(progressAnimation);
        animation.start();
    }

}

圆形进度View:

package com.sefford.circularprogressdrawable.sample;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.Scroller;

public class MyCircle extends View {
	/**
	 * 画笔对象的引用
	 */
	private Paint[] paints;
	RectF oval;
	/**
	 * 圆环的颜色
	 */
	private int roundColor;
	/**
	 * 圆环的宽度
	 */
	private float roundWidth;
	/**
	 * 圆环进度的颜色
	 */
	private int roundProgressColor;

	/**
	 * 移动
	 */
	Scroller scroller;

	public MyCircle(Context context) {
		this(context, null);
	}

	public MyCircle(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public MyCircle(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs);
		paints = new Paint[4];
		for (int i = 0; i < paints.length; i++) {
			paints[i] = new Paint();
		}
		oval = new RectF();

		TypedArray mTypedArray = context.getTheme().obtainStyledAttributes(
				attrs, R.styleable.myRound, defStyleAttr, 0);

		roundColor = mTypedArray.getColor(R.styleable.myRound_myRoundColor,
				Color.GRAY);
		roundWidth = mTypedArray.getDimension(R.styleable.myRound_myRoundWidth,
				3);
		roundProgressColor = mTypedArray.getColor(
				R.styleable.myRound_myRoundProgressColor, Color.RED);
		mTypedArray.recycle();

//		AccelerateInterpolator localAccelerateInterpolator = new AccelerateInterpolator();
//		this.scroller = new Scroller(context, localAccelerateInterpolator);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// super.onDraw(canvas);
		float centre = getWidth() / 2; // 获取圆心的x坐标
		float radius = (centre - roundWidth / 2); // 圆环的半径

		paints[0].setColor(roundColor); // 设置圆环的颜色
		paints[0].setStyle(Paint.Style.STROKE); // 设置空心
		paints[0].setStrokeWidth(roundWidth); // 设置圆环的宽度
		paints[0].setAntiAlias(true); // 消除锯齿
		paints[0].setStrokeCap(Paint.Cap.ROUND);// 圆角

		canvas.drawCircle(centre, centre, radius, paints[0]); // 画出圆环

		paints[0].setColor(roundProgressColor);
		// 用于定义的圆弧的形状和大小的界限.指定圆弧的外轮廓矩形区域
		// 椭圆的上下左右四个点(View 左上角为0)
		oval.set(centre - radius, centre - radius, centre + radius, centre
				+ radius);

		//画圆弧
		canvas.drawArc(oval, -90, progress, false, paints[0]);

		/**
		 * 画进度百分比的text
		 */
		paints[0].setStrokeWidth(0);
		paints[0].setColor(roundColor);
		paints[0].setTextSize(14);
		paints[0].setTypeface(Typeface.DEFAULT_BOLD); // 设置字体
		float textWidth = paints[0].measureText(progressText + "%");
		canvas.drawText(progressText + "%", centre - textWidth / 2,
				centre + 14 / 2, paints[0]); // 画出进度百分比
	}

	public static final String PROGRESS_PROPERTY = "progress";

	protected float progress;
	protected float progressText;

	public float getProgress() {
		return progress;
	}

	public void setProgress(float progress) {
		this.progress = progress * 360 / 100;
		invalidate();// UI thread
		// postInvalidate();//non-UI thread.
	}

	public void dodo(float progressText, float progress) {
		this.progressText = progressText;
		this.progress = progress;
		
		//也可使用3.0的AnimationSet实现
//		AnimationSet set = new AnimationSet(true);
//		set.setRepeatCount(AnimationSet.INFINITE);
//		set.setInterpolator(new AccelerateDecelerateInterpolator());
//		set.start();
//		this.setAnimation(set);
		 
		//4.0以上,在AnimationSet基础上封装的,遗憾的是没有Repeat
		AnimatorSet animation = new AnimatorSet();

		ObjectAnimator progressAnimation = ObjectAnimator.ofFloat(this,"progress", 0f, progress);
		progressAnimation.setDuration(700);// 动画执行时间

		/*
		 * AccelerateInterpolator      					加速,开始时慢中间加速 
		 * DecelerateInterpolator      					减速,开始时快然后减速 
		 * AccelerateDecelerateInterolator  					先加速后减速,开始结束时慢,中间加速
		 * AnticipateInterpolator      	 				反向 ,先向相反方向改变一段再加速播放
		 * AnticipateOvershootInterpolator 					反向加超越,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值 
		 * BounceInterpolator       						跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
		 * CycleIinterpolator         					循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2 *
		 * mCycles * Math.PI * input) LinearInterpolator    线性,线性均匀改变
		 * OvershottInterpolator       					超越,最后超出目的值然后缓慢改变到目的值
		 * TimeInterpolator          						一个接口,允许你自定义interpolator,以上几个都是实现了这个接口
		 */
		progressAnimation.setInterpolator(new AccelerateDecelerateInterpolator());

		animation.playTogether(progressAnimation);//动画同时执行,可以做多个动画
		animation.start();
	}

}

还有属性文件attrs.xml:

<!-- 圆形进度条 -->
<declare-styleable name="myRoundProgress">
    <attr name="myRoundColor" format="color" />
    <attr name="myRoundProgressColor" format="color" />
    <attr name="myRoundWidth" format="dimension" />
    <attr name="myRoundTextSize" format="dimension" />
</declare-styleable>


  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Android 圆形进度条可以通过自定义 View 或者使用第三方库来实现。以下是一种简单的实现方式: 1. 创建一个自定义 View 类,继承自 View 或者 ProgressBar。 2. 在自定义 View 的构造方法中初始化画笔和属性。 3. 重写 onDraw 方法,在该方法中绘制圆形进度条。 4. 使用属性动画或者定时器来更新进度值,并调用 invalidate 方法触发重绘。 下面是一个简单的示例代码: ```java public class CircleProgressBar extends View { private Paint backgroundPaint; private Paint progressPaint; private RectF arcRect; private int progress; private int maxProgress; public CircleProgressBar(Context context) { super(context); init(); } public CircleProgressBar(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { backgroundPaint = new Paint(); backgroundPaint.setColor(Color.GRAY); backgroundPaint.setStyle(Paint.Style.STROKE); backgroundPaint.setStrokeWidth(10); progressPaint = new Paint(); progressPaint.setStyle(Paint.Style.STROKE); progressPaint.setStrokeWidth(10); progressPaint.setStrokeCap(Paint.Cap.ROUND); arcRect = new RectF(); progress = 0; maxProgress = 100; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int centerX = getWidth() / 2; int centerY = getHeight() / 2; int radius = Math.min(centerX, centerY) - 10; arcRect.set(centerX - radius, centerY - radius, centerX + radius, centerY + radius); // 绘制背景圆弧 canvas.drawArc(arcRect, 0, 360, false, backgroundPaint); // 绘制进度圆弧 float sweepAngle = 360 * ((float) progress / maxProgress); Shader shader = new SweepGradient(centerX, centerY, Color.RED, Color.BLUE); progressPaint.setShader(shader); canvas.drawArc(arcRect, -90, sweepAngle, false, progressPaint); } public void setProgress(int progress) { this.progress = progress; invalidate(); } public void setMaxProgress(int maxProgress) { this.maxProgress = maxProgress; } } ``` 使用时,可以在布局文件中添加该自定义 View,并通过调用 `setProgress` 方法来更新进度值。 相关问题: 1. 如何创建一个自定义 View? 2. 如何绘制圆形进度条? 3. 如何使用属性动画来更新进度值? 4. 如何使用定时器来更新进度值? 5. 如何使用第三方库来实现圆形进度条

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值