You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Xamarin.Android中通过ObjectAnimator代码实现基于PathData的动画?

在Xamarin.Android中用ObjectAnimator结合PathData实现动画

我来帮你搞定Xamarin.Android里用ObjectAnimator结合PathData做动画的事儿,之前你用XML实现的逻辑,转成代码其实只需这几步:


1. 准备VectorDrawable资源

首先确保你的VectorDrawable(比如Resources/drawable/ic_animated_vector.xml)里包含需要动画的Path元素,给它设置android:name方便后续获取:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:name="animatedPath"
        android:pathData="M -7,-7 l 14,0 c 0,0 0,0 0,0 l 0,14 c 0,0 0,0 0,0 l -14,0 c 0,0 0,0 0,0 l 0,-14 c 0,0 0,0 0,0 Z"
        android:fillColor="#FF0000"/>
</vector>

2. 创建自定义PathData属性

Android的Path类没有直接的setPathData方法,我们得自定义一个Property来处理PathData字符串到Path对象的转换:

using Android.Animation;
using Android.Graphics;

public class PathDataProperty : Property<Path, string>
{
    private static PathDataProperty _instance;

    private PathDataProperty() : base(typeof(string), "pathData")
    {
    }

    // 单例模式避免重复创建
    public static PathDataProperty Instance => _instance ??= new PathDataProperty();

    public override string Get(Path objectValue)
    {
        // 动画中不需要获取当前PathData,返回null即可
        return null;
    }

    public override void Set(Path objectValue, string value)
    {
        if (string.IsNullOrEmpty(value)) return;
        
        objectValue.Reset();
        // 将PathData字符串解析为Path并填充
        PathParser.CreatePathFromPathData(value).FillPath(objectValue);
    }
}

3. 编写动画核心代码

在Activity/Fragment中,获取控件、VectorDrawable和目标Path,然后创建并启动ObjectAnimator:

using AndroidX.AppCompat.Widget;
using AndroidX.Graphics.Drawables;
using Android.Animation;

// 获取显示动画的ImageView
var imageView = FindViewById<AppCompatImageView>(Resource.Id.animatedImageView);

// 创建兼容低版本的VectorDrawable实例
var vectorDrawable = VectorDrawableCompat.Create(Resources, Resource.Drawable.ic_animated_vector, null);
imageView.SetImageDrawable(vectorDrawable);

// 获取VectorDrawable中需要动画的Path
var targetPath = vectorDrawable.GetPathByName("animatedPath");
if (targetPath == null) return;

// 定义动画的起始和目标PathData(你提供的两段路径)
var initialPathData = "M -7,-7 l 14,0 c 0,0 0,0 0,0 l 0,14 c 0,0 0,0 0,0 l -14,0 c 0,0 0,0 0,0 l 0,-14 c 0,0 0,0 0,0 Z";
var targetPathData = "M 7,-9 c 0,0 -14,0 -14,0 c -1.1044921875,0 -2,0.8955078125 -2,2 c 0,0 0,14 0,14 c 0,1.1044921875 0.8955078125,2 2,2 c 0,0 14,0 14,0 c 1.1044921875,0 2,-0.8955078125 2,-2 c 0,0 0,-14 0,-14 c 0,-1.1044921875 -0.8955078125,-2 -2,-2 Z";

// 创建ObjectAnimator,指定目标对象、自定义属性、插值器和路径值
var pathAnimator = ObjectAnimator.OfObject(
    targetPath,
    PathDataProperty.Instance,
    new PathEvaluator(), // 实现路径间的平滑过渡插值
    initialPathData,
    targetPathData
);

// 设置动画时长,和你XML里的166ms一致
pathAnimator.Duration = 166;

// 添加更新监听,动画每一帧都刷新控件,否则看不到变化
pathAnimator.AddUpdateListener(new AnimatorUpdateListener(anim =>
{
    vectorDrawable.InvalidateSelf();
    imageView.Invalidate();
}));

// 启动动画
pathAnimator.Start();

辅助类:AnimatorUpdateListener

因为Xamarin需要实现Java接口,我们做个简单的包装类:

public class AnimatorUpdateListener : Java.Lang.Object, IAnimatorUpdateListener
{
    private readonly Action<Animator> _onUpdate;

    public AnimatorUpdateListener(Action<Animator> onUpdate)
    {
        _onUpdate = onUpdate;
    }

    public void OnAnimationUpdate(ValueAnimator animation)
    {
        _onUpdate?.Invoke(animation);
    }
}

关键注意事项

  • 依赖AndroidX:PathParser和VectorDrawableCompat需要AndroidX库支持,确保你的项目已经引用了Xamarin.AndroidX相关包。
  • 路径插值:必须用PathEvaluator处理路径过渡,不然动画会很生硬。
  • 强制刷新:动画更新时一定要调用InvalidateSelf()和Invalidate()触发视图重绘,否则动画不会显示。

内容的提问来源于stack exchange,提问作者yoganathan k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:11:44