我有一个动画行为类,例如:
public class BaseAnimationBehavior : Behavior<View>
{
protected View associatedObject;
protected Easing _easingFunction;
private readonly BindableProperty EasingFunctionProperty = BindableProperty.Create(nameof(EasingFunction), typeof(string), typeof(BaseAnimationBehavior), defaultValue: "Linear", propertyChanged: (b, o, n) => OnEasingFunctionChanged(b, (string)o, (string)n));
private readonly BindableProperty ScaleProperty = BindableProperty.Create(nameof(Scale), typeof(double), typeof(BaseAnimationBehavior), defaultValue: 1.25);
public string EasingFunction
{
get { return (string)GetValue(EasingFunctionProperty); }
set { SetValue(EasingFunctionProperty, value); }
}
public double Scale
{
get { return (double)GetValue(ScaleProperty); }
set { SetValue(ScaleProperty, value); }
}
protected override void OnAttachedTo(View bindable)
{
associatedObject = bindable;
associatedObject.SizeChanged += AnimateItem;
}
protected override void OnDetachingFrom(View bindable)
{
associatedObject.SizeChanged -= AnimateItem;
}
private static Easing GetEasing(string easingName)
{
switch (easingName)
{
case "BounceIn": return Easing.BounceIn;
case "BounceOut": return Easing.BounceOut;
case "CubicInOut": return Easing.CubicInOut;
case "CubicOut": return Easing.CubicOut;
case "Linear": return Easing.Linear;
case "SinIn": return Easing.SinIn;
case "SinInOut": return Easing.SinInOut;
case "SinOut": return Easing.SinOut;
case "SpringIn": return Easing.SpringIn;
case "SpringOut": return Easing.SpringOut;
default: throw new ArgumentException(easingName + " is not valid");
}
}
private static void OnEasingFunctionChanged(BindableObject bindable, string oldvalue, string newvalue)
{
var obj = bindable as BaseAnimationBehavior;
if (obj == null)
{
return;
}
obj.EasingFunction = newvalue;
obj._easingFunction = GetEasing(newvalue);
}
private void AnimateItem(object sender, EventArgs e)
{
await associatedObject.TranslateTo(associatedObject.TranslationX, associatedObject.TranslationY - 10, 10, _easingFunction);
await associatedObject.TranslateTo(associatedObject.TranslationX, associatedObject.TranslationY + 10, 900, _easingFunction);
}
}
在XAML页面中,我应用如下动画:
<StackLayout IsVisible="{Binding AProp}">
<Entry Text="{Binding AField}" IsEnabled="True">
<Entry.Behaviors>
<Entry.Behaviors:BaseAnimationBehavior EasingFunction="SinInOut" />
</Entry.Behaviors>
</Entry>
</StackLayout>
当AProp
变为true时,就会由于SizeChanged
事件而产生动画。
当AProp
变为false时,由于整个StackLayout被隐藏,动画将无法运行或不可见。
我使用MVVM,并且有一个视图模型,它被绑定到如下视图:
public class MyViewModel
{
public bool AProp { get { return _prop; } set { _prop = value; RaisePropertyChanged ....; } }
public string AField { get { return _field; } set { _field = value; RaisePropertyChanged ....; } }
public void DoSomething() {
if(condition) { AProp = true; } else { AProp = false; }
}
}
如何实现隐藏元素时先进行动画处理然后隐藏它的情况?
答案 0 :(得分:0)
如果使用视图模型隐藏,则需要向视图发送某种信号,表明该属性已更改。
如果出于某种原因必须从视图模型中隐藏控件,我建议