[英]How to animate column width in UWP App
在我的UWP應用程序中,我有一個有2列的網格。 該應用程序是自適應的,在移動設備上我只想一次顯示一列。 有沒有辦法使用動畫來減少第1列的寬度並從第2列擴展寬度,反之亦然?
在XAML框架中,動畫大小和布局一直很棘手。 為什么? 不是因為你不能動畫Width
,你可以,但是性能通常很糟糕,因為對Width
/ Height
的更改會自動觸發布局更新,然后在UI線程上進行大量重新計算,重新測量和重新排列內容這會傷害到性能。
但是你總能做一些變通辦法。 使用Windows Composition API ,現在可以更輕松地為布局更改設置動畫,同時保持每秒60幀的新鮮率,這一切都要歸功於新的API,如ImplicitAnimations
, SetImplicitHideAnimation
和SetImplicitShowAnimation
。
ImplicitAnimations
基本上允許您監視屬性更改,如Opacity
, Offset
, Size
等,每當更新時,舊值將平滑地動畫到新值; 其中SetImplicitHideAnimation
和SetImplicitShowAnimation
將在元素的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.