实战一:翻转动画
自定义view:
package com.test.animation.view;
import android.content.Context;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import com.test.animation.Utils;
import androidx.annotation.Nullable;
public class FancyFlipView extends View {
private static final float PADDING = Utils.dpToPixel(100);
private static final float IMAGE_WIDTH = Utils.dpToPixel(200);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Camera camera = new Camera();
float topFlip = 0;
float bottomFlip = 0;
float flipRotation = 0;
public FancyFlipView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
{
camera.setLocation(0, 0, Utils.getZForCamera()); // -8 = -8 * 72
}
public float getTopFlip() {
return topFlip;
}
public void setTopFlip(float topFlip) {
this.topFlip = topFlip;
invalidate();
}
public float getBottomFlip() {
return bottomFlip;
}
public void setBottomFlip(float bottomFlip) {
this.bottomFlip = bottomFlip;
invalidate();
}
public float getFlipRotation() {
return flipRotation;
}
public void setFlipRotation(float flipRotation) {
this.flipRotation = flipRotation;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 绘制上半部分
canvas.save();
canvas.translate(PADDING + IMAGE_WIDTH / 2, PADDING + IMAGE_WIDTH / 2);
canvas.rotate(-flipRotation);
camera.save();
camera.rotateX(topFlip);
camera.applyToCanvas(canvas);
camera.restore();
canvas.clipRect(- IMAGE_WIDTH, - IMAGE_WIDTH, IMAGE_WIDTH, 0);
canvas.rotate(flipRotation);
canvas.translate(- (PADDING + IMAGE_WIDTH / 2), - (PADDING + IMAGE_WIDTH / 2));
canvas.drawBitmap(Utils.getAvatar(getResources(), (int) IMAGE_WIDTH), PADDING, PADDING, paint);
canvas.restore();
// 绘制下半部分
canvas.save();
canvas.translate(PADDING + IMAGE_WIDTH / 2, PADDING + IMAGE_WIDTH / 2);
canvas.rotate(-flipRotation);
camera.save();
camera.rotateX(bottomFlip);
camera.applyToCanvas(canvas);
camera.restore();
canvas.clipRect(- IMAGE_WIDTH, 0, IMAGE_WIDTH, IMAGE_WIDTH);
canvas.rotate(flipRotation);
canvas.translate(- (PADDING + IMAGE_WIDTH / 2), - (PADDING + IMAGE_WIDTH / 2));
canvas.drawBitmap(Utils.getAvatar(getResources(), (int) IMAGE_WIDTH), PADDING, PADDING, paint);
canvas.restore();
}
}
使用:
/**
* 自定义属性动画集合
*/
ObjectAnimator bottomFlipAnimator = ObjectAnimator.ofFloat(view, "bottomFlip", 45);
bottomFlipAnimator.setDuration(1500);
ObjectAnimator flipRotationAnimator = ObjectAnimator.ofFloat(view, "flipRotation", 270);
flipRotationAnimator.setDuration(1500);
ObjectAnimator topFlipAnimator = ObjectAnimator.ofFloat(view, "topFlip", - 45);
topFlipAnimator.setDuration(1500);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playSequentially(bottomFlipAnimator, flipRotationAnimator, topFlipAnimator);
animatorSet.setStartDelay(1000);
animatorSet.start();
实战二:自定义插值器练习,文字变化插值器
/**
* 自定义文字变换插值器
*/
ObjectAnimator animator = ObjectAnimator.ofObject(view, "province", new ProvinceEvaluator(), "澳门特别行政区");
animator.setDuration(10000);
animator.start();
class ProvinceEvaluator implements TypeEvaluator {
@Override
public String evaluate(float fraction, String startValue, String endValue) {
// 北京市 上海市 fraction 0.5f
int startIndex = ProvinceUtil.provinces.indexOf(startValue);
int endIndex = ProvinceUtil.provinces.indexOf(endValue);
int index = (int) (startIndex + (endIndex - startIndex) * fraction);
return ProvinceUtil.provinces.get(index);
}
}
package com.test.animation.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import com.test.animation.Utils;
import androidx.annotation.Nullable;
public class ProvinceView extends View {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
String province = "北京市";
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
invalidate();
}
public ProvinceView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
{
// setLayerType(LAYER_TYPE_SOFTWARE, null);
setLayerType(LAYER_TYPE_HARDWARE, null);
// setLayerType(LAYER_TYPE_NONE, null);
paint.setTextSize(Utils.dpToPixel(60));
paint.setTextAlign(Paint.Align.CENTER);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawText(province, getWidth() / 2, getHeight() / 2, paint);
}
}