#对于APP首页,设计比较炫丽复杂.导致进入会因为数据没有加载出来比较难看.在数据加载期间增加一个过度动画显得比较和谐好看.
#.自定义view实现动画效果.
public class SplashView extends View {
//旋转画笔
private Paint mPaint;
//扩散画笔
private Paint mHolePaint;
//属性动画
private ValueAnimator mValueAnimator;
//背景色;
private int mBackgroundColor= Color.WHITE;
private int [] mCircleColors;
//旋转中心坐标;
private float mCenterX;
private float mCenterY;
//表示斜对角线长度一半,扩散圆最大半径;
private float mDistance;
//6个球的半径;
private float mCircleRadius=18;
//旋转最大半径;
private float mRotateRadius=90;
//当前大圆的旋转角度;
private float mCurrentRotateAngle=0F;
//大圆半径
private float mCurrentRotateRadius=mRotateRadius;
//扩散半径
private float mCurrentHoleRadius=0F;
//旋转动画时长;
private long mRotateDuration=1200;
public SplashView(Context context) {
this(context,null);
}
public SplashView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public SplashView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
mPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
mHolePaint=new Paint(Paint.ANTI_ALIAS_FLAG);
mHolePaint.setStyle(Paint.Style.STROKE);
mHolePaint.setColor(mBackgroundColor);
mCircleColors=context.getResources().getIntArray(R.array.splash_circle_colors);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mCenterX=w*1f/2;
mCenterY=h*1f/2;
mDistance= (float) (Math.hypot(w,h)/2);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mState==null){
mState=new RotateState();
}
mState.drawState(canvas);
}
private SplashState mState;
private abstract class SplashState{
abstract void drawState(Canvas canvas);
}
//旋转
private class RotateState extends SplashState{
private RotateState(){
mValueAnimator=ValueAnimator.ofFloat(0, (float) (Math.PI*2));
mValueAnimator.setRepeatCount(2);
mValueAnimator.setDuration(mRotateDuration);
mValueAnimator.setInterpolator(new LinearInterpolator());
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mCurrentRotateAngle= (float) valueAnimator.getAnimatedValue();
invalidate();
}
});
mValueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mState=new MerginState();
}
});
mValueAnimator.start();
}
@Override
void drawState(Canvas canvas) {
drawBackground(canvas);
drawCircles(canvas);
}
}
private void drawCircles(Canvas canvas) {
float rotate= (float) (Math.PI*2/mCircleColors.length);
for (int i = 0; i < mCircleColors.length; i++) {
float angle=i*rotate+mCurrentRotateAngle;
float cx= (float) (Math.cos(angle)*mCurrentRotateRadius+mCenterX);
float cY= (float) (Math.sin(angle)*mCurrentRotateRadius+mCenterY);
mPaint.setColor(mCircleColors[i]);
canvas.drawCircle(cx,cY,mCircleRadius,mPaint);
}
}
private void drawBackground(Canvas canvas){
if (mCurrentHoleRadius>0){
float stoke=mDistance-mCurrentHoleRadius;
float radius=stoke/2+mCurrentHoleRadius;
mHolePaint.setStrokeWidth(stoke);
canvas.drawCircle(mCenterX,mCenterY,radius,mHolePaint);
}else{
canvas.drawColor(mBackgroundColor);
}
}
//扩散聚合
private class MerginState extends SplashState{
private MerginState(){
mValueAnimator=ValueAnimator.ofFloat(18, 90);
// mValueAnimator.setRepeatCount(1);
mValueAnimator.setDuration(mRotateDuration);
mValueAnimator.setInterpolator(new OvershootInterpolator(20f));
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mCurrentRotateRadius= (float) valueAnimator.getAnimatedValue();
invalidate();
}
});
mValueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mState=new ExpandState();
}
});
mValueAnimator.reverse();
}
@Override
void drawState(Canvas canvas) {
drawBackground(canvas);
drawCircles(canvas);
}
}
//水波纹
private class ExpandState extends SplashState{
public ExpandState(){
mValueAnimator=ValueAnimator.ofFloat(mCircleRadius, mDistance);
// mValueAnimator.setRepeatCount(1);
mValueAnimator.setDuration(mRotateDuration);
mValueAnimator.setInterpolator(new LinearInterpolator());
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mCurrentHoleRadius= (float) valueAnimator.getAnimatedValue();
invalidate();
}
});
mValueAnimator.start();
}
@Override
void drawState(Canvas canvas) {
drawBackground(canvas);
// drawCircles(canvas);
}
}
}
#2使用
<com.example.mypaint.SplashView
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>