Android自定义菊花进度条
2017-09-15 15:18
295 查看
先说废话
这几天要做一个跟ios一样的菊花进度条,刚开始让UI切了一张图片,然后看看怎么转起来,发现android动画里没有这样的动画,毕竟菊花的每根线是只改变透明度,不改变位置的。最后想到了自定义控件。然后UI又改了样式,这个控件用不到了,写这里保存。
这个菊花口有点大啊,没办法,ui给的要求就是这样。有没有bug我不知道,因为没有经过线上的考验,但是至少思路是这么回事。
public class LoadingProgressBar extends ProgressBar { private static final String TAG = "LoadingProgressBar"; public LoadingProgressBar(Context context) { super(context); } public LoadingProgressBar(Context context, AttributeSet attrs) { super(context, attrs); loadAttrs(context, attrs); initPaint(); } public LoadingProgressBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } /*view的默认宽度*/ private int mWidth; /*view的默认高度*/ private int mHeight; /*线条粗细*/ private int paintBold; /*线条长度*/ private int lineLength; /*背景线条颜色*/ private int bgPaintColor; /*上层线条颜色*/ // private int beforePaintColor; /*进度文字颜色*/ private int textColor; /*线条个数*/ private int lines; /*背景画笔*/ private Paint bgPaint; /*前景画笔*/ private Paint bfPaint; /*进度文字画笔*/ private Paint textPaint; /*当前下载进度*/ private int progress; /*最大进度*/ private int max; /*循环绘制*/ private int circle; private Handler handler = new Handler(); /** * 加载我们在attrs.xml文件的自定义的属性 */ private void loadAttrs(Context context, AttributeSet attrs) { TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.loading_progress); paintBold = array.getDimensionPixelSize(R.styleable.loading_progress_paintBold, 10); lineLength = array.getDimensionPixelSize(R.styleable.loading_progress_lineLength, 25); bgPaintColor = array.getColor(R.styleable.loading_progress_backgroundColor, Color.GRAY); // beforePaintColor = array.getColor(R.styleable.loading_progress_beforeColor, Color.YELLOW); lines = array.getInt(R.styleable.loading_progress_lines, 12); max = array.getInt(R.styleable.loading_progress_max, 100); progress = array.getInt(R.styleable.loading_progress_progress, 0); // textColor = array.getColor(R.styleable.loading_progress_textColor, Color.BLACK); array.recycle(); } /** * 初始化画笔 */ private void initPaint() { bgPaint = new Paint(); bgPaint.setColor(bgPaintColor); bgPaint.setAntiAlias(true); bgPaint.setStrokeWidth(paintBold); //使得画笔更加圆滑 bgPaint.setStrokeJoin(Paint.Join.ROUND); bgPaint.setStrokeCap(Paint.Cap.ROUND); // bfPaint = new Paint(); // bfPaint.setColor(beforePaintColor); // bfPaint.setAntiAlias(true); // bfPaint.setStrokeWidth(paintBold); // bfPaint.setStrokeJoin(Paint.Join.ROUND); // bfPaint.setStrokeCap(Paint.Cap.ROUND); // textPaint = new Paint(); // textPaint.setColor(textColor); // textPaint.setAntiAlias(true); // textPaint.setTextAlign(Paint.Align.CENTER); // textPaint.setTextSize(40); circle = 0; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //获取view的宽度 mWidth = getViewSize(100, widthMeasureSpec); //获取view的高度 mHeight = getViewSize(100, heightMeasureSpec); } /** * 测量模式 表示意思 * UNSPECIFIED 父容器没有对当前View有任何限制,当前View可以任意取尺寸 * EXACTLY 当前的尺寸就是当前View应该取的尺寸 * AT_MOST 当前尺寸是当前View能取的最大尺寸 * * @param defaultSize 默认大小 * @param measureSpec 包含测量模式和宽高信息 * @return 返回View的宽高大小 */ private int getViewSize(int defaultSize, int measureSpec) { int viewSize = defaultSize; //获取测量模式 int mode = MeasureSpec.getMode(measureSpec); //获取大小 int size = MeasureSpec.getSize(measureSpec); switch (mode) { case MeasureSpec.UNSPECIFIED: //如果没有指定大小,就设置为默认大小 viewSize = defaultSize; break; case MeasureSpec.AT_MOST: //如果测量模式是最大取值为size //我们将大小取最大值,你也可以取其他值 viewSize = size; break; case MeasureSpec.EXACTLY: //如果是固定的大小,那就不要去改变它 viewSize = size; break; } return viewSize; } @Override protected void onDraw(Canvas canvas) { // super.onDraw(canvas); int x = mWidth / 2; int y = mHeight / 2; int r = x - 5; int alpha = 255;//范围0-255. for (int i = 0; i < lines; i++) {//从circle到circle+2最亮,其他依次减小 //circle=0,亮2.1.0; circle =1,亮1.0.11; circle = 2,亮0.11.10; circle = 3,亮11.10.9; circle = 4,亮10.9.8;.....circle = 11,亮1.2.3 switch (circle) { case 0: if (i == 2 || i == 1 || i == 0) { alpha = 255; } else { alpha = (int) (255 * (1 - 0.1 * (i + circle - 2)));//i=3,亮度0.9;i=4,亮度0.8....i=11亮度0.1 } break; case 1: if (i == 1 || i == 0 || i == 11) { alpha = 255; } else { alpha = (int) (255 * (1 - 0.1 * (i + circle - 2)));//i=2,亮度0.9;i=3,亮度0.8....i=10亮度0.1 } break; case 2: if (i == 0 || i == 11 || i == 10) { alpha = 255; } else { alpha = (int) (255 * (1 - 0.1 * (i + circle - 2)));//i=1,亮度0.9;i=4,亮度0.8....i=11亮度0.1 } break; default: if (i == 12 - circle + 0 || i == 12 - circle + 1 || i == 12 - circle + 2) { alpha = 255; } else { alpha = (int) (255 * (1 - 0.1 * (i + circle - 2)));//i=1,亮度0.9;i=4,亮度0.8....i=11亮度0.1 } break; } Log.e(TAG, "circle = " + circle + " i= " + i + " , alpha= " + alpha); bgPaint.setAlpha(alpha); canvas.drawLine(x, y - r, x, y - r + lineLength, bgPaint); canvas.rotate(-360 / lines, x, y); } circle++; if (circle == 12) { circle = 0; } handler.postDelayed(runnable, 50); } private Runnable runnable = new Runnable() { @Override public void run() { invalidate(); } }; @Override protected void onDetachedFromWindow() { handler.removeCallbacks(runnable); super.onDetachedFromWindow(); } /** * 为进度设置动画 * ValueAnimator是整个属性动画机制当中最核心的一个类,属性动画的运行机制是通过不断地对值进行操作来实现的, * 而初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的。 * 它的内部使用一种时间循环的机制来计算值与值之间的动画过渡, * 我们只需要将初始值和结束值提供给ValueAnimator,并且告诉它动画所需运行的时长, * 那么ValueAnimator就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果。 * * @param start 开始值 * @param current 结束值 * @param duration 动画时长 */ public void startAnimation(int start, int current, int duration) { ValueAnimator progressAnimator = ValueAnimator.ofInt(start, current); progressAnimator.setDuration(duration); progressAnimator.setTarget(progress); progressAnimator.setInterpolator(new BounceInterpolator()); progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { progress = (int) animation.getAnimatedValue(); invalidate(); } }); progressAnimator.start(); } /*设置进度最大值*/ // public void setMax(int max) { // this.max = max; // invalidate(); // } /*设置当前进度*/ // public void setProgress(int progress) { // this.progress = progress; // invalidate(); // } } //然后是使用 <com.hyphenate.easeui.widget.LoadingProgressBar android:layout_width="80dp" android:layout_height="80dp" android:layout_centerInParent="true" loading_progress_:backgroundColor="#9f9c9c" loading_progress_:lineLength="10dp" loading_progress_:lines="12" loading_progress_:max="100" loading_progress_:paintBold="3dp" loading_progress_:progress="70" />
相关文章推荐
- android 进度条 自定义菊花
- Android自定义View——菊花进度条
- Android自定义View和属性动画完美结合,创造出酷炫圆环动画,带标尺和进度
- Android自定义标题+画圆+进度条
- Android带圆形数字进度的自定义进度条示例
- Android自定义半圆进度条 半圆渐变色进度条带指示 半圆开口大小可自由修改
- Android自定义圆形渐变进度条
- Android 自定义View修炼-高仿猎豹清理大师自定义内存开口圆环比例进度View
- android 自定义view+属性动画实现充电进度条
- Android自定义圆形按钮点击进度动画
- Android Launcher 自定义View 炫酷换壁纸效果,水瓶加水进度显示效果
- Android 自定义漂亮的圆形进度条
- Android自定义圆形进度条,完成类似LOFTER效果
- android自定义view实现水平进度条
- Android学习系列(3)--App自动更新之自定义进度视图和内部存储
- Android自定义圆形进度条
- Android自定义view圆形进度条
- android自定义渐变进度条
- Android自定义View--圆形进度条RoundProgress
- android 自定义 环形进度条