簡體   English   中英

如何在UWP App中為列寬設置動畫

[英]How to animate column width in UWP App

在我的UWP應用程序中,我有一個有2列的網格。 該應用程序是自適應的,在移動設備上我只想一次顯示一列。 有沒有辦法使用動畫來減少第1列的寬度並從第2列擴展寬度,反之亦然?

在XAML框架中,動畫大小和布局一直很棘手。 為什么? 不是因為你不能動畫Width ,你可以,但是性能通常很糟糕,因為對Width / Height的更改會自動觸發布局更新,然后在UI線程上進行大量重新計算,重新測量和重新排列內容這會傷害到性能。

但是你總能做一些變通辦法。 使用Windows Composition API ,現在可以更輕松地為布局更改設置動畫,同時保持每秒60幀的新鮮率,這一切都要歸功於新的API,如ImplicitAnimationsSetImplicitHideAnimationSetImplicitShowAnimation

ImplicitAnimations基本上允許您監視屬性更改,如OpacityOffsetSize等,每當更新時,舊值將平滑地動畫到新值; 其中SetImplicitHideAnimationSetImplicitShowAnimation將在元素的Visibility更改時簡單地設置動畫。 因此,不是立即消失,一個元素可以縮小和淡出。

請注意,您需要為API提供所需的動畫,以了解如何設置動畫。 為了讓您的生活更輕松,我創建了一些輔助方法(請參見底部的鏈接),它封裝了您通常需要的一些關鍵動畫。

要了解他們的確切行為,請查看下面的gif

在此輸入圖像描述

我正在重新定位,隱藏和顯示處於不同自適應視覺狀態的元素,沒有動畫在XAML中編寫,但是使用以下代碼, Composition API只是隱式地處理所有這些更改的動畫。

var compositor = this.Visual().Compositor;

// Create background visuals.
var leftBackgroundVisual = compositor.CreateSpriteVisual();
leftBackgroundVisual.Brush = compositor.CreateColorBrush(Colors.Crimson);
LeftGridBackgroundVisualWrapper.SetChildVisual(leftBackgroundVisual);

var middleBackgroundVisual = compositor.CreateSpriteVisual();
middleBackgroundVisual.Brush = compositor.CreateColorBrush(Colors.Gold);
MiddleGridBackgroundVisualWrapper.SetChildVisual(middleBackgroundVisual);

var rightBackgroundVisual = compositor.CreateSpriteVisual();
rightBackgroundVisual.Brush = compositor.CreateColorBrush(Colors.DarkOrchid);
RightGridBackgroundVisualWrapper.SetChildVisual(rightBackgroundVisual);

// Sync background visual dimensions.
LeftGridBackgroundVisualWrapper.SizeChanged += (s, e) => leftBackgroundVisual.Size = e.NewSize.ToVector2();
MiddleGridBackgroundVisualWrapper.SizeChanged += (s, e) => middleBackgroundVisual.Size = e.NewSize.ToVector2();
RightGridBackgroundVisualWrapper.SizeChanged += (s, e) => rightBackgroundVisual.Size = e.NewSize.ToVector2();

// Enable implilcit Offset and Size animations.
LeftText.EnableImplicitAnimation(VisualPropertyType.Offset, 400);
MiddleText.EnableImplicitAnimation(VisualPropertyType.Offset, 400);
RightText.EnableImplicitAnimation(VisualPropertyType.Offset, 400);
LeftGrid.EnableImplicitAnimation(VisualPropertyType.Offset, 400);
MiddleGrid.EnableImplicitAnimation(VisualPropertyType.Offset, 400);
RightGrid.EnableImplicitAnimation(VisualPropertyType.Offset, 400);
leftBackgroundVisual.EnableImplicitAnimation(VisualPropertyType.Size, 400);
middleBackgroundVisual.EnableImplicitAnimation(VisualPropertyType.Size, 400);
rightBackgroundVisual.EnableImplicitAnimation(VisualPropertyType.Size, 400);

// Enable implicit Visible/Collapsed animations.
LeftGrid.EnableFluidVisibilityAnimation(showFromScale: 0.6f, hideToScale: 0.8f, showDuration: 400, hideDuration: 250);
MiddleGrid.EnableFluidVisibilityAnimation(showFromScale: 0.6f, hideToScale: 0.8f, showDelay: 200, showDuration: 400, hideDuration: 250);
RightGrid.EnableFluidVisibilityAnimation(showFromScale: 0.6f, hideToScale: 0.8f, showDelay: 400, showDuration: 400, hideDuration: 250);

有很多代碼所以我不會在這里發布所有內容。 但請隨意從此鏈接中查看

您可以使用bind來執行此操作。 你應該在Page中創建兩個屬性,代碼如下。

   public static readonly DependencyProperty RcProperty = DependencyProperty.Register(
        "Rc", typeof(double), typeof(MainPage), new PropertyMetadata(100d));

    public double Rc
    {
        get { return (double) GetValue(RcProperty); }
        set { SetValue(RcProperty, value); }
    }

    public static readonly DependencyProperty LcProperty = DependencyProperty.Register(
        "Lc", typeof(double), typeof(MainPage), new PropertyMetadata(500d));

    public double Lc
    {
        get { return (double) GetValue(LcProperty); }
        set { SetValue(LcProperty, value); }
    }

但我們不能將雙重綁定到GridLength,我們應該添加轉換。

public class DoubletoGridConvert : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var n = (double) value;
        return new GridLength(n);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

在我們編寫之后,我們可以使頁面如下所示。

      <Grid>
          <Grid.RowDefinitions>
              <RowDefinition Height="{x:Bind Rc,Mode=OneWay,Converter={StaticResource double}}"/>
              <RowDefinition Height="{x:Bind Lc,Mode=OneWay,Converter={StaticResource double}}"/>
          </Grid.RowDefinitions>
          <Grid Background="#FF565656"></Grid>
          <Grid Grid.Row="1" Background="#FFa2a2a2"></Grid>
      </Grid>
      <Button Margin="47,662,0,10" Content="set" Click="Button_OnClick"></Button>

點擊按鈕時我們進行動畫制作。

    private void Button_OnClick(object sender, RoutedEventArgs e)
    {
        this.Name = nameof(MainPage);
        var storyboard = new Storyboard();
        var animation = new DoubleAnimation();
        Storyboard.SetTargetName(animation, nameof(MainPage));
        Storyboard.SetTarget(animation, this);
        Storyboard.SetTargetProperty(animation,"Rc");
        animation.EnableDependentAnimation = true;
        animation.From = 100;
        animation.To = 200;
        animation.Duration = new Duration(TimeSpan.FromMilliseconds(500));
        storyboard.Children.Add(animation);
        storyboard.Begin();

        storyboard = new Storyboard();
        animation = new DoubleAnimation();
        Storyboard.SetTarget(animation, this);
        Storyboard.SetTargetName(animation,nameof(MainPage));
        Storyboard.SetTargetProperty(animation, nameof(Lc));
        animation.From = 500;
        animation.To = 150;
        animation.Duration = new Duration(TimeSpan.FromMilliseconds(500));
        animation.EnableDependentAnimation = true;
        storyboard.Children.Add(animation);

        storyboard.Begin();
    }

我認為它可以幫到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM