Xamarin Forms:带有 OpacityProperty BindableProperty 的动画

Xamarin Forms: Animations with OpacityProperty BindableProperty

在 ViewModel 中,我有一个名为 IsButtonVisible 的依赖项 属性,要么是 true 要么是 false。

在视图层中,我有需要显示或隐藏的布局,具体取决于 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();
    }
}

问题是涉及到能见度时它是突然的。

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

谢谢。

你没有在你的 ViewModel 中添加视图(动画)逻辑,因为这会破坏它对 ContentPage/View/...的独立性,测试变得困难等等,...(很多所以 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);
    }
}