本文实例为大家分享了Android自定义View实现进度条动画的具体代码,供大家参考,具体内容如下
控件效果
原理:
控制代码/
/更新进度值 val mHandler = object : Handler() { override fun handleMessage(msg: Message?) { progressView.setCurrentProgress(progress1.toFloat()) } } //开启动画,更新进度值 private fun progressAdd() { isAnimate = true progress1 = 0 Thread(Runnable { while (isAnimate) { Thread.sleep(random.nextInt(200).toLong()) progress1 += 1 mHandler.sendEmptyMessage(0) } }).start() } //停止动画 private fun progressReduce() { isAnimate = false }
控件源码:
public class ProgressView extends View { //前景颜色 private int FIRST_COLOR = 0xffFEA711; // 0xff00574B;// //背景颜色 private int SECOND_COLOR = 0xffFBE39C; private int mSecondWidth; private int mFirstWidth; private int mHeight; private int mSecondRadius; private int mFirstRadius; private int progressPadding = 30; private float currentValue; private int maxProgress = 100; //画笔 private Paint paint; private RectF rectF; private Bitmap leafBitmap; private int mLeafWidth; private int mLeafHeight; private List<Leaf> mLeafInfos; public ProgressView(Context context) { super(context, null); } public ProgressView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public ProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); paint = new Paint(); paint.setStyle(Paint.Style.FILL); paint.setColor(FIRST_COLOR); paint.setAntiAlias(true); rectF = new RectF(); leafBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.icon_leaf); mLeafWidth = leafBitmap.getWidth(); mLeafHeight = leafBitmap.getHeight(); Log.e("zhen", " mLeafWidth: " + mLeafWidth + " mLeafHeight: " + mLeafHeight); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mHeight = h; //外围 mSecondWidth = w; mSecondRadius = (int) ((mSecondWidth * 1f / 5) / 2); //内部进度条 mFirstWidth = mSecondWidth - progressPadding - mSecondRadius; mFirstRadius = mSecondRadius - progressPadding; mLeafInfos = new LeafFactory(mFirstRadius - mLeafWidth, 6).generateLeafs(); Log.e("zhen", " mSecondWidth: " + mSecondWidth + " mHeight: " + mHeight + " mSecondRadius: " + mSecondRadius + " mFirstWidth: " + mFirstWidth + " mFirstRadius: " + mFirstRadius); } public void setCurrentProgress(float currentProgress) { Log.e("zhen", "currentProgress: " + currentProgress); if (currentProgress > 100) return; currentValue = currentProgress / maxProgress * mFirstWidth; invalidate(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //画布移动 canvas.translate(mSecondRadius, mHeight / 2); //画背景左半圆 paint.setStyle(Paint.Style.FILL); paint.setColor(SECOND_COLOR); rectF.left = -mSecondRadius; rectF.top = -mSecondRadius; rectF.right = mSecondRadius; rectF.bottom = mSecondRadius; canvas.drawArc(rectF, 90, 180, false, paint); //画背景右半圆 rectF.left = mSecondWidth - 3 * mSecondRadius; rectF.top = -mSecondRadius; rectF.right = mSecondWidth - mSecondRadius; rectF.bottom = mSecondRadius; canvas.drawArc(rectF, -90, 180, false, paint); //画背景中间方形 rectF.left = 0; rectF.top = -mSecondRadius; rectF.right = mSecondWidth - 2 * mSecondRadius; rectF.bottom = mSecondRadius; canvas.drawRect(rectF, paint); //绘制进度条半圆 paint.setColor(FIRST_COLOR); float leftValue = (mFirstRadius - currentValue) > 0 ? (mFirstRadius - currentValue) : 0; float angel = (float) Math.toDegrees(Math.acos(leftValue / mFirstRadius)); rectF.left = -mFirstRadius; rectF.top = -mFirstRadius; rectF.right = mFirstRadius; rectF.bottom = mFirstRadius; canvas.drawArc(rectF, 180 - angel, 2 * angel, false, paint); //绘制进度条方形 if (currentValue >= mFirstRadius) { currentValue = currentValue > mFirstWidth ? mFirstWidth : currentValue; rectF.left = 0; rectF.top = -mFirstRadius; rectF.right = currentValue - mFirstRadius; rectF.bottom = mFirstRadius; canvas.drawRect(rectF, paint); } //落叶纷飞 if (currentValue > 0 && currentValue < mFirstWidth) { long currentTime = System.currentTimeMillis(); for (int i = 0; i < mLeafInfos.size(); i++) { Leaf leaf = mLeafInfos.get(i); int delay = (int) ((currentTime - leaf.startTime) % CIRCLE_TIME); leaf.x = mFirstWidth - mFirstRadius - delay * (mFirstWidth * 1f / CIRCLE_TIME); if (leaf.x + mFirstRadius + mLeafWidth < currentValue) continue; leaf.y = (float) (leaf.amplitude * Math.sin(2 * Math.PI / CIRCLE_TIME * delay + leaf.phaseOffeset)); Log.e("zhen", "延时ms数" + delay + " 角速度: " + (2 * Math.PI / CIRCLE_TIME) + " leaf.x: " + leaf.x + " leaf.y: " + leaf.y); // 通过Matrix控制叶子旋转 Matrix matrix = new Matrix(); matrix.postTranslate(leaf.x, leaf.y); // 根据叶子旋转方向确定叶子旋转角度 float rotate = leaf.rotateOrientation ? leaf.x % 360f : -leaf.x % 360; matrix.postRotate(rotate, leaf.x + mLeafWidth / 2, leaf.y + mLeafHeight / 2); Log.e("zhen", "落叶子旋转角度: " + rotate); canvas.drawBitmap(leafBitmap, matrix, paint); } } //绘制旋转风车 paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(10); float x = mSecondWidth - 2 * mSecondRadius; float y = 0; canvas.drawCircle(x, y, mSecondRadius, paint); paint.setStyle(Paint.Style.FILL); paint.setColor(0XFFFCD158); canvas.drawCircle(x, y, mSecondRadius - 5, paint); } @IntDef({Amplitude.SMALL, Amplitude.MIDDLE, Amplitude.LARGE}) public @interface Amplitude { int SMALL = 0; int MIDDLE = 1; int LARGE = 2; } public static class Leaf { public static long CIRCLE_TIME = 3000; //一个周期所需要的时间 //振幅大小 private int amplitude; //初始相位偏移 private int phaseOffeset; //旋转方向 private boolean rotateOrientation; //延时时间 private long startTime; //x位置取决于初始位置偏移 private float x; //y位置取决于振幅,初始相位 private float y; @Override public String toString() { return "Leaf{" + "amplitude=" + amplitude + ", phaseOffeset=" + phaseOffeset + ", rotateOrientation=" + rotateOrientation + ", startTime=" + startTime + ", x=" + x + ", y=" + y + '}'; } } public static class LeafFactory { private Random random = new Random(); int randomValue; private int mHeight; private int mLeafSize; public LeafFactory(int mHeight, int mLeafSize) { this.mHeight = mHeight; this.mLeafSize = mLeafSize; } public List<Leaf> generateLeafs() { List<Leaf> mLeafsInfo = new ArrayList<>(); for (int i = 0; i < mLeafSize; i++) { mLeafsInfo.add(generateLeaf()); } return mLeafsInfo; } private Leaf generateLeaf() { Leaf leaf = new Leaf(); randomValue = random.nextInt(3); switch (randomValue) { case Amplitude.SMALL: leaf.amplitude = (int) (mHeight * 1f / 3); break; case Amplitude.MIDDLE: leaf.amplitude = (int) (mHeight * 2f / 3); break; case Amplitude.LARGE: leaf.amplitude = (int) (mHeight * 3f / 3); break; } leaf.startTime = random.nextInt((int) CIRCLE_TIME); leaf.phaseOffeset = random.nextInt(8); leaf.rotateOrientation = random.nextBoolean(); Log.e("zhen", "生成一个叶子:" + leaf); return leaf; } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。