代码之家  ›  专栏  ›  技术社区  ›  Snake Eyes

在xaml xamarin和C中更改IsVisible时向上滑动动画#

  •  0
  • Snake Eyes  · 技术社区  · 7 年前

    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

    什么时候 如果设置为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; }
       }
    }
    

    1 回复  |  直到 7 年前
        1
  •  0
  •   Scarnet    7 年前

    如果使用视图模型隐藏,则需要向视图发送某种信号,表明属性已更改。

    如果出于某种原因必须从视图模型中隐藏控件,我建议

    • 覆盖视图模型中更改的RaisePropertyChanged
    • 在属性名称上引发事件是AProb
    • 在视图中订阅该事件