Android Animator与ObjectAnimator咨询:新手求动画实现方案
Android动画进阶实现思路
你说的没错,Android Studio确实没有内置的Animation可视化编辑视图。除了你已经尝试的XML属性动画集合(代码已翻译注释如下),这里分享几个相对小众但实用的实现思路:
<set android:ordering=["同时执行" | "顺序执行"]> <objectAnimator android:propertyName="属性名" android:duration="时长(毫秒)" android:valueFrom="起始值(浮点数 | 整数 | 颜色)" android:valueTo="目标值(浮点数 | 整数 | 颜色)" android:startOffset="延迟时长(毫秒)" android:repeatCount="重复次数" android:repeatMode=["重启" | "反向播放"] android:valueType=["整数类型" | "浮点类型"]/> <animator android:duration="时长(毫秒)" android:valueFrom="起始值(浮点数 | 整数 | 颜色)" android:valueTo="目标值(浮点数 | 整数 | 颜色)" android:startOffset="延迟时长(毫秒)" android:repeatCount="重复次数" android:repeatMode=["重启" | "反向播放"] android:valueType=["整数类型" | "浮点类型"]/> <set> ... </set> </set>
1. 利用Paint的Shader实现自定义渐变动画
很多属性动画只能修改View的固有属性,而通过Paint的Shader可以实现更复杂的渐变流动效果,比如按钮扫光、文字渐变填充。核心思路是在自定义View的onDraw方法中,动态更新Shader的位置或参数,再通过invalidate()触发重绘:
public class ShaderAnimView extends View { private Paint mPaint; private LinearGradient mGradient; private Matrix mMatrix; private int mTranslateX; public ShaderAnimView(Context context) { super(context); init(); } private void init() { mPaint = new Paint(); // 创建左右渐变的Shader,颜色从透明到白色再到透明 mGradient = new LinearGradient(-getWidth(), 0, 0, 0, new int[]{Color.TRANSPARENT, Color.WHITE, Color.TRANSPARENT}, new float[]{0f, 0.5f, 1f}, Shader.TileMode.CLAMP); mPaint.setShader(mGradient); mMatrix = new Matrix(); // 启动动画 ValueAnimator animator = ValueAnimator.ofInt(0, getWidth()); animator.setDuration(1500); animator.setRepeatCount(ValueAnimator.INFINITE); animator.addUpdateListener(animation -> { mTranslateX = (int) animation.getAnimatedValue(); invalidate(); }); animator.start(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 更新Shader的位置 mMatrix.setTranslate(mTranslateX, 0); mGradient.setLocalMatrix(mMatrix); // 绘制文字或图形 canvas.drawText("扫光动画", 50, 100, mPaint); } }
2. 用PathMeasure实现路径跟随动画
如果需要让View沿着自定义曲线移动(比如圆形、波浪形轨迹),PathMeasure可以精准获取路径上任意位置的坐标和切线方向,结合ValueAnimator就能实现轨迹动画,还能同步控制View的旋转方向:
// 先创建路径,比如一个圆形 Path path = new Path(); path.addCircle(300, 300, 200, Path.Direction.CW); PathMeasure measure = new PathMeasure(path, false); float pathLength = measure.getLength(); ValueAnimator animator = ValueAnimator.ofFloat(0, 1); animator.setDuration(2000); animator.setRepeatCount(ValueAnimator.INFINITE); animator.addUpdateListener(animation -> { float value = (float) animation.getAnimatedValue(); float[] pos = new float[2]; float[] tan = new float[2]; // 获取当前进度对应的路径点坐标和切线方向 measure.getPosTan(pathLength * value, pos, tan); // 设置View的位置(居中对齐路径点) view.setTranslationX(pos[0] - view.getWidth()/2); view.setTranslationY(pos[1] - view.getHeight()/2); // 计算旋转角度,让View始终沿着路径切线方向 float angle = (float) (Math.atan2(tan[1], tan[0]) * 180 / Math.PI); view.setRotation(angle); }); animator.start();
3. 借助TransitionDrawable实现图层切换动画
这个组件可以快速实现两个Drawable之间的淡入淡出切换,不需要复杂的属性动画配置,适合按钮状态切换、图片渐变替换等场景:
// 准备两个要切换的Drawable Drawable drawable1 = getResources().getDrawable(R.drawable.ic_state_normal); Drawable drawable2 = getResources().getDrawable(R.drawable.ic_state_selected); TransitionDrawable transitionDrawable = new TransitionDrawable(new Drawable[]{drawable1, drawable2}); button.setBackground(transitionDrawable); // 启动切换动画,时长500毫秒 transitionDrawable.startTransition(500); // 如果需要反向切换,调用reverseTransition(500)
4. 自定义TypeEvaluator实现非线性动画
系统默认的动画多是线性或简单插值,自定义TypeEvaluator可以实现弹性、弹跳等物理效果,比如模拟弹簧回弹:
// 自定义弹性Evaluator class SpringEvaluator implements TypeEvaluator<Float> { // 弹性系数,值越大弹性越强 private float mStiffness = 0.2f; // 阻尼系数,值越大衰减越快 private float mDamping = 0.8f; @Override public Float evaluate(float fraction, Float startValue, Float endValue) { float diff = endValue - startValue; // 用简谐运动公式计算当前值 float value = (float) (diff * (1 - Math.exp(-fraction / mStiffness) * Math.cos(fraction * Math.PI / mDamping))); return startValue + value; } } // 使用这个Evaluator创建动画 ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationY", 0, 300); animator.setEvaluator(new SpringEvaluator()); animator.setDuration(1500); animator.start();
内容的提问来源于stack exchange,提问作者Shubham Sevak
相关产品推荐
相关产品推荐

