Material Design Style Widget(二)──MaterialRadioButton(续)
来源:互联网 发布:琉璃神社换的域名2017 编辑:程序博客网 时间:2024/06/06 17:03
前言
最近和同学聊天、看别人的博客,发现自己实现的方式太繁琐了,有很大的优化空间。在这里,利用自定义 Interpolator、属性动画的两个类 ValueAnimator 和 ObjectAnimator对我之前的实现进行优化。
优化
1.利用自定义interpolator,来实现一个Animation 的逆向 Animation。即可以少自定义一个 Animation 类。
final static class CounterAnticipateInterpolator implements Interpolator{ private float mTension; CounterAnticipateInterpolator() { mTension = 2.0f; } CounterAnticipateInterpolator(int mTension) { this.mTension = mTension; } @Override public float getInterpolation(float t) { return 1 - (t * t * ((mTension + 1) * t - mTension)); } }
2.当然也可以通过 valueAnimtor 的 addUpdateListener 实现节拍器,不必去自定义 Animation 类。
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1); if (checked){ valueAnimator.setInterpolator(new OvershootInterpolator()); } else { valueAnimator.setInterpolator(new CounterAnticipateInterpolator()); } valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { update((Float) animation.getAnimatedValue()); } }); valueAnimator.setDuration(300); valueAnimator.start();
3.当然我们还可以更进一步,自定义 property,利用 ObjectAnimator,自动的去改变绘制参数,而不必手动的去 update。
private float interpolatedTime; public float getInterpolatedTime() { return interpolatedTime; } public void setInterpolatedTime(float interpolatedTime) { this.interpolatedTime = interpolatedTime; } private static final Property<MaterialRadioButton, Float> MATERIAL_RADIO_BUTTON_PROGRESS_PROPERTY = new Property<MaterialRadioButton, Float>(Float.class, "MATERIAL_RADIO_BUTTON_PROGRESS_PROPERTY") { @Override public void set(MaterialRadioButton object, Float value) { object.setInterpolatedTime(value); } @Override public Float get(MaterialRadioButton object) { return object.getInterpolatedTime(); } }; ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(this, MATERIAL_RADIO_BUTTON_PROGRESS_PROPERTY, 0 , 1); if (checked){ objectAnimator.setInterpolator(new OvershootInterpolator()); } else { objectAnimator.setInterpolator(new CounterAnticipateInterpolator()); } objectAnimator.setDuration(300); objectAnimator.start();
源码
1.最终版源码
package com.sinaapp.myron.myronmaterialdesign.widget;import android.animation.ObjectAnimator;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.util.Property;import android.view.View;import android.view.animation.Interpolator;import android.view.animation.OvershootInterpolator;public class MaterialRadioButton extends View { private float cx; private float cy; private float outerRingRadius; private float innerCircleRadiusMax; private float innerCircleRadius; private Paint outerBgRingPaint; private Paint outerFgRingPaint; private Paint innerCirclePaint; private int mainColor; private boolean checked; private float interpolatedTime; public float getInterpolatedTime() { return interpolatedTime; } public void setInterpolatedTime(float interpolatedTime) { this.interpolatedTime = interpolatedTime; } private static final Property<MaterialRadioButton, Float> MATERIAL_RADIO_BUTTON_PROGRESS_PROPERTY = new Property<MaterialRadioButton, Float>(Float.class, "MATERIAL_RADIO_BUTTON_PROGRESS_PROPERTY") { @Override public void set(MaterialRadioButton object, Float value) { object.setInterpolatedTime(value); } @Override public Float get(MaterialRadioButton object) { return object.getInterpolatedTime(); } }; public MaterialRadioButton(Context context) { super(context); } public MaterialRadioButton(Context context, AttributeSet attrs) { super(context, attrs); } public MaterialRadioButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); init(); } private void init() { int sideLength = Math.min(getWidth(), getHeight()); float halfSideLength = sideLength * 0.5f; cx = halfSideLength; cy = halfSideLength; outerRingRadius = halfSideLength * 0.875f; float outerRingStrokeWidth = halfSideLength * 0.25f; innerCircleRadiusMax = halfSideLength * 0.45f; mainColor = Color.parseColor("#009688"); int outerBgRingColor = Color.parseColor("#616161"); outerBgRingPaint = new Paint(); outerBgRingPaint.setAntiAlias(true); outerBgRingPaint.setStyle(Paint.Style.STROKE); outerBgRingPaint.setStrokeWidth(outerRingStrokeWidth); outerBgRingPaint.setColor(outerBgRingColor); outerFgRingPaint = new Paint(); outerFgRingPaint.setAntiAlias(true); outerFgRingPaint.setStyle(Paint.Style.STROKE); outerFgRingPaint.setStrokeWidth(outerRingStrokeWidth); outerFgRingPaint.setColor(Color.parseColor("#00ffffff")); innerCirclePaint = new Paint(); innerCirclePaint.setAntiAlias(true); innerCirclePaint.setStyle(Paint.Style.FILL); innerCirclePaint.setColor(Color.parseColor("#00ffffff")); checked = false; setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { checked = !checked; anim(); } }); } @Override protected void onDraw(Canvas canvas) { calculateDrawParams(); canvas.drawCircle(cx, cy, outerRingRadius, outerBgRingPaint); canvas.drawCircle(cx, cy, outerRingRadius, outerFgRingPaint); canvas.drawCircle(cx, cy, innerCircleRadius, innerCirclePaint); } private void anim() { ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(this, MATERIAL_RADIO_BUTTON_PROGRESS_PROPERTY, 0, 1); if (checked) { objectAnimator.setInterpolator(new OvershootInterpolator()); } else { objectAnimator.setInterpolator(new CounterAnticipateInterpolator()); } objectAnimator.setDuration(300); objectAnimator.start(); } final static class CounterAnticipateInterpolator implements Interpolator { private float mTension; CounterAnticipateInterpolator() { mTension = 2.0f; } CounterAnticipateInterpolator(int mTension) { this.mTension = mTension; } @Override public float getInterpolation(float t) { return 1 - (t * t * ((mTension + 1) * t - mTension)); } } private void calculateDrawParams() { //update color of outer foreground ring int outerFgRingColor = Color.argb(clamp((int) (interpolatedTime * 255), 0, 255), Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); outerFgRingPaint.setColor(outerFgRingColor); //update color of inner circle int innerCircleColor = Color.argb(clamp((int) (interpolatedTime * 255), 0, 255), Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); innerCirclePaint.setColor(innerCircleColor); //update radius of inner circle innerCircleRadius = innerCircleRadiusMax * interpolatedTime; invalidate(); } private int clamp(int value, int low, int high) { return Math.min(Math.max(value, low), high); }}
2.开发版源码
package com.sinaapp.myron.myronmaterialdesign.widget;import android.animation.Animator;import android.animation.ObjectAnimator;import android.animation.ValueAnimator;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.util.Property;import android.view.View;import android.view.animation.AlphaAnimation;import android.view.animation.Animation;import android.view.animation.AnticipateInterpolator;import android.view.animation.Interpolator;import android.view.animation.OvershootInterpolator;import android.view.animation.Transformation;public class MaterialRadioButton extends View { private float cx; private float cy; private float outerRingRadius; private float innerCircleRadiusMax; private float innerCircleRadius; private Paint outerBgRingPaint; private Paint outerFgRingPaint; private Paint innerCirclePaint; private int mainColor; private boolean checked; private float interpolatedTime; public float getInterpolatedTime() { return interpolatedTime; } public void setInterpolatedTime(float interpolatedTime) { this.interpolatedTime = interpolatedTime; } private static final Property<MaterialRadioButton, Float> MATERIAL_RADIO_BUTTON_PROGRESS_PROPERTY = new Property<MaterialRadioButton, Float>(Float.class, "MATERIAL_RADIO_BUTTON_PROGRESS_PROPERTY") { @Override public void set(MaterialRadioButton object, Float value) { object.setInterpolatedTime(value); } @Override public Float get(MaterialRadioButton object) { return object.getInterpolatedTime(); } }; public MaterialRadioButton(Context context) { super(context); } public MaterialRadioButton(Context context, AttributeSet attrs) { super(context, attrs); } public MaterialRadioButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); init(); } private void init() { int sideLength = Math.min(getWidth(), getHeight()); float halfSideLength = sideLength * 0.5f; cx = halfSideLength; cy = halfSideLength; outerRingRadius = halfSideLength * 0.875f; float outerRingStrokeWidth = halfSideLength * 0.25f; innerCircleRadiusMax = halfSideLength * 0.45f; mainColor = Color.parseColor("#009688"); int outerBgRingColor = Color.parseColor("#616161"); outerBgRingPaint = new Paint(); outerBgRingPaint.setAntiAlias(true); outerBgRingPaint.setStyle(Paint.Style.STROKE); outerBgRingPaint.setStrokeWidth(outerRingStrokeWidth); outerBgRingPaint.setColor(outerBgRingColor); outerFgRingPaint = new Paint(); outerFgRingPaint.setAntiAlias(true); outerFgRingPaint.setStyle(Paint.Style.STROKE); outerFgRingPaint.setStrokeWidth(outerRingStrokeWidth); outerFgRingPaint.setColor(Color.parseColor("#00ffffff")); innerCirclePaint = new Paint(); innerCirclePaint.setAntiAlias(true); innerCirclePaint.setStyle(Paint.Style.FILL); innerCirclePaint.setColor(Color.parseColor("#00ffffff")); checked = false; setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { checked = !checked; anim(); } }); } @Override protected void onDraw(Canvas canvas) { calculateDrawParams(); canvas.drawCircle(cx, cy, outerRingRadius, outerBgRingPaint); canvas.drawCircle(cx, cy, outerRingRadius, outerFgRingPaint); canvas.drawCircle(cx, cy, innerCircleRadius, innerCirclePaint); } private void anim(){ ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(this, MATERIAL_RADIO_BUTTON_PROGRESS_PROPERTY, 0 , 1); if (checked){ objectAnimator.setInterpolator(new OvershootInterpolator()); } else { objectAnimator.setInterpolator(new CounterAnticipateInterpolator()); } objectAnimator.setDuration(300); objectAnimator.start(); /* ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1); if (checked){ valueAnimator.setInterpolator(new OvershootInterpolator()); } else { valueAnimator.setInterpolator(new CounterAnticipateInterpolator()); } valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { update((Float) animation.getAnimatedValue()); } }); valueAnimator.setDuration(300); valueAnimator.start(); */// Animation animation = new AlphaAnimation(1, 1); /* animation = new CheckAnimation(); if (checked){ animation.setInterpolator(new OvershootInterpolator()); } else { animation.setInterpolator(new CounterAnticipateInterpolator()); } */ /* if (checked){ animation = new CheckAnimation(); animation.setInterpolator(new OvershootInterpolator()); } else { animation = new UnCheckAnimation(); animation.setInterpolator(new AnticipateInterpolator()); } */// animation.setDuration(300);// animation.setRepeatMode();// startAnimation(animation); }/* class CheckAnimation extends Animation { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { update(interpolatedTime); } } */final static class CounterAnticipateInterpolator implements Interpolator{ private float mTension; CounterAnticipateInterpolator() { mTension = 2.0f; } CounterAnticipateInterpolator(int mTension) { this.mTension = mTension; } @Override public float getInterpolation(float t) { return 1 - (t * t * ((mTension + 1) * t - mTension)); } }/* class UnCheckAnimation extends Animation { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { update(1 - interpolatedTime); } }*/ private void calculateDrawParams() { //update color of outer foreground ring int outerFgRingColor = Color.argb(clamp((int) (interpolatedTime * 255), 0, 255), Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); outerFgRingPaint.setColor(outerFgRingColor); //update color of inner circle int innerCircleColor = Color.argb(clamp((int) (interpolatedTime * 255), 0, 255), Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); innerCirclePaint.setColor(innerCircleColor); //update radius of inner circle innerCircleRadius = innerCircleRadiusMax * interpolatedTime; invalidate(); }/* private void update(float interpolatedTime) { //update color of outer foreground ring int outerFgRingColor = Color.argb(clamp((int) (interpolatedTime * 255), 0, 255), Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); outerFgRingPaint.setColor(outerFgRingColor); //update color of inner circle int innerCircleColor = Color.argb(clamp((int) (interpolatedTime * 255), 0, 255), Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); innerCirclePaint.setColor(innerCircleColor); //update radius of inner circle innerCircleRadius = innerCircleRadiusMax * interpolatedTime; invalidate(); }*/ private int clamp(int value, int low, int high) { return Math.min(Math.max(value, low), high); }}
0 0
- Material Design Style Widget(二)──MaterialRadioButton(续)
- Material Design Style Widget(二)──MaterialRadioButton
- Material Design Style Widget(一)──MaterialCheckBox
- Material Design Style Widget(三)──MaterialProgress
- Android:Material Design - Style - Color(转)
- Material Design 之Style(三)
- material design(二) MaterialEditText
- Material Design动画(二)
- Material Design入门(二)
- Material Design学习(二)
- Material Design 学习(二)
- Days40 Material Design(二)
- Material Design动画(二)
- Material Design 动画 (二)
- android material design widget recyclerview
- Android:Material Design - Style - Color
- Material Design控件使用(二)
- Material Design for Developers(二)开始
- 根文件系统的制作
- Light OJ Aladdin and the Flying Carpet(约数个数)
- Android中Service的意义及用法
- 第一次写——ACM
- 【Linux】在Ubuntu中安装Eclipse与Helloworld
- Material Design Style Widget(二)──MaterialRadioButton(续)
- Java实现重构二叉树
- LeetCode Maximal Rectangle
- 第六周上机实践项目1——深复制体验(1)
- Android 程序框架设计
- Redis学习备忘 Jedis
- 在枚举类型的值和字符串之间相互转换
- linux下64位汇编的系统调用(5)
- 数据库调优教程(十二) 优化sql语句