Android自定义View动画(进度条)
2015-11-27 19:29
441 查看
转载请标明出处:http://blog.csdn.net/u013598111/article/details/50073869,本文出自:【JunTao_sun】
效果图:
![](https://img-blog.csdn.net/20151127192358822?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
天好冷,好想吃面包,好想钻被窝玩手机,不多说,上代码,关键的都注释了。
可以继续改善和优化-----
效果图:
天好冷,好想吃面包,好想钻被窝玩手机,不多说,上代码,关键的都注释了。
可以继续改善和优化-----
<span style="font-size:18px;">package com.example.circle; import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.animation.LinearInterpolator; public class MyView extends View { // 灰色画笔 private Paint mGrayPaint; // 画圆笔 private Paint mCirclePaint; // 文字画笔 private Paint mTextPaint; private int padding = 10; // 半径 private int radius = 25; // 控件宽度 private int width; // 控件高度 private int height; // 默认3个圆 private int numberCircle = 3; // 减去padding的实际宽度 private int realWidth; // 每一行的宽度 private int eachLineWidth; // 连接线的数目 private int lineSum = numberCircle - 1; private String firstTitle = "每日一句"; private String secondTitle = "阳光灿烂"; private String lastTitle = "橘子群岛"; private Rect mRect = new Rect(); // 文字的距离控件中心的距离 private int topPadding = 40; private float changeValue = 0; private boolean isFirst = true; private int paintStyleRadius = 5; private Paint mCircle; public MyView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mCirclePaint.setDither(true); mCirclePaint.setColor(Color.parseColor("#FF6600")); mCirclePaint.setStyle(Paint.Style.STROKE); mCirclePaint.setStrokeCap(Paint.Cap.ROUND); mCirclePaint.setStyle(Paint.Style.FILL); mCircle = new Paint(Paint.ANTI_ALIAS_FLAG); mCircle.setDither(true); mCircle.setColor(Color.parseColor("#FF6600")); mCircle.setStyle(Paint.Style.STROKE); mCircle.setStrokeCap(Paint.Cap.ROUND); mCircle.setStrokeWidth(2); mGrayPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mGrayPaint.setDither(true); mGrayPaint.setStyle(Paint.Style.FILL_AND_STROKE); mGrayPaint.setStrokeWidth(5); mGrayPaint.setColor(0xaaa1afc9); mGrayPaint.setStrokeCap(Paint.Cap.ROUND); // 设置绘制时各图形的结合方式,如平滑效果等 mGrayPaint.setStrokeJoin(Paint.Join.ROUND); mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mTextPaint.setDither(true); mTextPaint.setColor(Color.parseColor("#0066FF")); initAniamtionPaint(); } private Paint mPaintAnimaL; private void initAniamtionPaint() { mPaintAnimaL = new Paint(Paint. 4000 ANTI_ALIAS_FLAG); mPaintAnimaL.setDither(true); mPaintAnimaL.setColor(Color.parseColor("#33FF33")); mPaintAnimaL.setStrokeWidth(5); mPaintAnimaL.setStrokeCap(Paint.Cap.ROUND); } public MyView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyView(Context context) { this(context, null); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec, heightMeasureSpec); textMeasure(); } private void textMeasure() { mTextPaint.getTextBounds(firstTitle, 0, firstTitle.length(), mRect); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { // TODO Auto-generated method stub super.onSizeChanged(w, h, oldw, oldh); this.width = w; this.height = h; realWidth = w - 2 * padding; // 线 得到最大的宽度 eachLineWidth = (realWidth - 6 * radius) / (numberCircle - 1); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 第一条线的起始 也就是left 2.5是笔刷的半径 不然会越界 int lineLeft = (int) (2 * radius + padding + 2.5); // 第一条线的right int lineRight = (int) (lineLeft + eachLineWidth); // 第二条线的起始 left (第一条线的末端right+圆的直径) int nextLineLeft = (int) (lineRight + 2 * (radius + 2.5) - 2.5); // 第二条线的right int nextLineRight = nextLineLeft + eachLineWidth; // 第一个圆的中心 半径加上leftpadding int circleCenter = (int) (radius + padding); // 第二个圆的下个中心点 2.5是笔刷的半径 不然会越界 int circleNextCenter = (int) (lineRight + radius + 2.5); // 第三个圆的中心点 2.5是笔刷的半径 不然会越界 int circleLastCenter = (int) (nextLineRight + radius + 2.5); // 统一高度 height / 2-长度(因为不能在控件的正中 底下还有文字) int unifyHeight = height / 2 - radius; // 第个描述文字的left (圆的中心减去文字宽度的一半) int firstTextLeft = circleCenter - mRect.width() / 2; // 统一的 文字的起始高度 文字最低高度 int unifyHeightWithText = height / 2 + topPadding; // 第二个文字描述的left int secondTextLeft = circleNextCenter - mRect.width() / 2; int lastTextLeft = circleLastCenter - mRect.width() / 2; // 画线*********************************************************************************** canvas.drawLine(lineLeft, unifyHeight, lineRight, unifyHeight, mGrayPaint); canvas.drawLine(nextLineLeft, unifyHeight, nextLineRight, unifyHeight, mGrayPaint); // 画圆*********************************************************************************** canvas.drawCircle(circleCenter, unifyHeight, radius, mCircle); canvas.drawCircle(circleNextCenter, unifyHeight, radius, mCircle); canvas.drawCircle(circleLastCenter, unifyHeight, radius, mCircle); // 画文字*********************************************************************************** canvas.drawText(firstTitle, firstTextLeft, unifyHeightWithText, mTextPaint); canvas.drawText(secondTitle, secondTextLeft, unifyHeightWithText, mTextPaint); canvas.drawText(lastTitle, lastTextLeft, unifyHeightWithText, mTextPaint); RectF iconRect = new RectF(); // 圆的外矩形 圆中心 减半径 iconRect.set(circleCenter - radius, unifyHeight - radius, circleCenter + radius, unifyHeight + radius); Path mpath = new Path(); mpath.addArc(iconRect, changeValue, changeValue); canvas.drawPath(mpath, mCirclePaint); if (isFirst) { // 开启一次 isFirst = false; // 初始化动画执行 先后类型 type = 1; lineType = 1; // 开始动画 verticalRun(); } // 动画进度************************************************************************************* if (isStart) { // 第一条线 的进度 float rateLineOne = lineRate1 * 1.0f / eachLineWidth * eachLineWidth; // 第二条线的进度 float rateLineTwo = lineRate2 * 1.0f / eachLineWidth * eachLineWidth; canvas.drawLine(lineLeft, unifyHeight, lineLeft + rateLineOne, unifyHeight, mPaintAnimaL); if (C2 == 2) {// 条件满足 既第一条线完就执行 // 第二个圆 iconRect.set(circleNextCenter - radius, unifyHeight - radius, circleNextCenter + radius, unifyHeight + radius); // 第二个;路径 Path mpath2 = new Path(); mpath.addArc(iconRect, 0, changeValue2); canvas.drawPath(mpath, mCirclePaint); } // 画线 if (flag2 == 2) canvas.drawLine(nextLineLeft, unifyHeight, nextLineLeft + rateLineTwo, unifyHeight, mPaintAnimaL); // 第三个圆 if (C3 == 3) { iconRect.set(circleLastCenter - radius, unifyHeight - radius, circleLastCenter + radius, unifyHeight + radius); // 第二个;路径 Path mpath3 = new Path(); mpath.addArc(iconRect, changeValue3, changeValue3); canvas.drawPath(mpath, mCirclePaint); } } } private float changeValue2; private float changeValue3; // changeValue的类型 private int type; private int lineType; // 画圆的标志 private int C2; private int C3; public void verticalRun() { final ValueAnimator animator = ValueAnimator.ofFloat(0, 360); animator.addListener(new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { // TODO Auto-generated method stub } @Override public void onAnimationRepeat(Animator animation) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animator animation) { if (C2 == 2) { flag2 = 2;// 第二条线的动画条件 lineType = 2;// 画第二条线 } if (C3 == 3) return;// 第三个圆结束动画 isStart = true; lineAniamtion(eachLineWidth); postInvalidate(); } @Override public void onAnimationCancel(Animator animation) { // TODO Auto-generated method stub } }); animator.setDuration(2000).start(); animator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { if (type == 1) { changeValue = (Float) animation.getAnimatedValue(); postInvalidate(); } if (type == 2) { changeValue2 = (Float) animation.getAnimatedValue(); postInvalidate(); } if (type == 3) { changeValue3 = (Float) animation.getAnimatedValue(); postInvalidate(); } } }); } private float lineRate1, lineRate2; private int flag, flag2; // 动画是否开始 private boolean isStart = false; public void lineAniamtion(int l) { ValueAnimator animator = ValueAnimator.ofFloat(0, l); animator.setDuration(2000).start(); animator.addListener(new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { // TODO Auto-generated method stub } @Override public void onAnimationRepeat(Animator animation) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animator animation) { C2 = 2;// 第一条线画完 执行第二个圆 动画 type = 2;// 第二个圆的变量值 // 如果当前二个条线画完 直接画第三个圆 if (lineType == 2) { C3 = 3; type = 3; } verticalRun(); postInvalidate(); } @Override public void onAnimationCancel(Animator animation) { // TODO Auto-generated method stub } }); animator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { if (lineType == 1) { // 第一条线的的进度值 lineRate1 = (Float) animation.getAnimatedValue(); postInvalidate(); } if (lineType == 2) { // 第二条线的的进度值 lineRate2 = (Float) animation.getAnimatedValue(); postInvalidate(); } } }); } } </span>
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories