如何使用 Xamarin 中的动画属性创建自定义视图

How to create custom views with properties for animating in Xamarin

我正在尝试向片段添加自定义过渡。正如 Link 所建议的那样,正确的解决方案是创建一个自定义视图作为片段容器,然后通过对新添加的 属性 进行动画处理,使片段的过渡 运行。但绝对是 java。我在 C# 和 Xamarin 中如下实现了它:

class SmartFrameLayout : FrameLayout
{

    public SmartFrameLayout(Context context) : base(context) { }
    public SmartFrameLayout(Context context, IAttributeSet attrs) : base(context, attrs) { }
    public SmartFrameLayout(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr) { }
    public SmartFrameLayout(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes) { }

    //public float getXFraction()
    //{
    //    if (Width == 0) return 0;
    //    return GetX() / Width;
    //}

    //public void setXFraction(float fraction)
    //{
    //    Log.Debug("Fraction", fraction.ToString());
    //    float xx = GetX();
    //    SetX(xx * fraction);
    //}

    //private float XFraction;


    public float XFraction
    {
        get {
            if (Width == 0) return 0;
            return GetX() / Width;
        }
        set {
            float xx = GetX();
            SetX(xx * value);
        }
    }

}

如您所见,首先我尝试实现与教程相同的方法(除了 c# 不支持只读局部变量作为 "final" 替换!) 但是在 objectAnimator 中 属性 没有正确调用。然后我想也许使用 C# 属性 会解决问题。但它没有。

这是我的动画 xml 文件,名称为 "from_right.xml":

<?xml version="1.0" encoding="utf-8" ?>
<objectAnimator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:propertyName="xFraction"
    android:valueType="floatType"
    android:valueFrom="1.0"
    android:valueTo="0"
    android:duration="500"/>

我将 属性Name 更改为 "XFraction" 或什至其他任何内容,但结果是一样的。

使用 "x" 作为 属性Name 和“1000”作为 valueFrom 效果很好。

所以我发现主要问题是objectAnimator根本无法调用setXFraction!

请告诉我哪里做错了,或者是否有更好的解决方案来准确获取 objectAnimator 中 valueFrom 的屏幕宽度!

您需要将 setXFractiongetXFraction 方法公开给 Java;它们目前仅在托管代码中,无法访问 Java VM。

使用 [Export] 属性将这些方法公开给 Java 以便动画师可以使用它们:

    [Export]
    public float getXFraction()
    {
        if (Width == 0) return 0;
        return GetX() / Width;
    }

    [Export]
    public void setXFraction(float fraction)
    {
        Log.Debug("Fraction", fraction.ToString());
        float xx = GetX();
        SetX(xx * fraction);
    }

这将导致在 SmartFrameLayoutAndroid Callable Wrapper 内生成以下 Java 代码:

public float getXFraction ()
{
    return n_getXFraction ();
}

private native float n_getXFraction ();


public void setXFraction (float p0)
{
    n_setXFraction (p0);
}

private native void n_setXFraction (float p0);