首页 > 解决方案 > Xamarin Forms:具有 OpacityProperty BindableProperty 的动画

问题描述

在 ViewModel 中,我有一个名为 IsButtonVisible 的依赖属性,它可以是真或假。

在视图层中,我需要显示或隐藏此布局,具体取决于 IsButtonVisible 的值。但我不想突然显示或隐藏它,我想平滑地淡入淡出。

我在网上看到这样做的方法是通过事件,例如在 3 秒内将控件淡入 0% 或 100%:

await image.FadeTo(0, 3000);
await image.FadeTo(1, 3000);

但现在我想通过数据绑定来做到这一点。旧代码是:

MyControl.SetBinding(IsVisibleProperty, "IsButtonVisible");

现在我需要使用平滑不透明度,我能达到的最远距离是:

MyControl.SetBinding(OpacityProperty, "IsButtonVisible", BindingMode.OneWay, new MyButtonConverter()););

public class MyButtonConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if ((bool)value)
            return 1; // 100%; visible

        return 0; // 0%; invisible
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

问题是它与可见性一样突然。

有没有办法可以在某处使用动画,无论是在数据绑定语句中还是在转换器内部?

谢谢。

标签: animationxamarindata-bindingxamarin.formsconverter

解决方案


您不需要在 ViewModel 中添加视图(动画)逻辑,因为这会破坏其对 ContentPage/View/...的独立性,测试变得困难,等等,...(很多关于此的 SO Q/As )。

因此,让我们假设您的 ViewModel 公开了一个属性更改事件、一个可分配的回调命令或操作,或一个 System.Reactive 主题(我个人的选择)等...对于您IsButtonVisible可以附加到您的属性View(不是 ViewModel) ,在 ContentPage .ator 中是这样的:

InitializeComponent();
BindingContext = viewModel = new AnimPageViewModel();
viewModel.PropertyChanged += ViewModel_PropertyChanged;

现在,当IsButtonVisible更改时您可以运行动画,此示例只是在每次该属性更改时来回切换不透明度。

async void ViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
    if (e.PropertyName == "IsButtonVisible")
    {
        await animateButton
            .FadeTo(
                Math.Abs(animateButton.Opacity) > double.Epsilon ? 0 : 1,
                2000,
                Math.Abs(animateButton.Opacity) < double.Epsilon ? Easing.CubicIn : Easing.CubicOut);
    }
}

推荐阅读