Blend 自定义横竖屏切换动画

今天写了一个小动画,把这几天研究的Blend相关知识简单的串接一下,效果那如下面几张图:

  

 

也就是在切换横竖屏的时候让按钮产生移动效果,来让他们在切换时移动到正确位置;还有就是横屏左和横屏右时切换,使用旋转加移动。

下面说下整个动画的制作流程

一、首先,创建一个Silverlight for Windows Phone应用程序,让它支持横竖屏,并默认为竖屏

SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"

把名为LayoutRoot的Grid控件里的所有子元素删除,并添加如下代码:

<Button x:Name="TopLeftButton" Content="Top Left" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="20,20,0,0" Width="200" />
<Button x:Name="TopRightButton" Content="Top Right"  HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,20,20,0" Width="200" />
<Button x:Name="BottomLeftButton" Content="Bottom Left"  HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="20,0,0,20" Width="200" />
<Button x:Name="BottomRightButton" Content="Bottom Right"  HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,20,20" Width="200" />

二、做好这些以后打开Blend(View->Open in Expression Blend)
在Blend的左上角选项卡中点击States,并点击Add state group按钮,添加一个名为OrientationStates的状态分组,并为此分组添加3个状态,分别为Portrait、LandscapeRight和LandscapeLeft。

1、接下来我们选中Portrait点击右边的Add transition的下拉列表选择Portrait->LandscapeRight(这一步是指定状态Portrait到状态LandscapeRight过程时),这时在Portrait节点下面出现LandscapeRight,我们点击LandscapeRight,这时在Objects and timeline会出现时间线,我们在时间线1秒时分别给4个按钮添加一个关键帧,点击 Record Keyframe。再在0秒时为TopLeftButton添加一个关键帧,并把Transform下“+”选项卡里的Y设置为371,同样做法分别设置TopRightButton的X为-489,BottomLeftButton的X为489,BottomRightButton的Y为-371。

重复这一步添加Portrait->LandscapeLeft这一状态转换,设置值为左上按钮0帧时X为489,右上Y为371,左下Y为-371,右下X位-489。

2、在LandscapeRight状态里重复和1类似的步骤添加LandscapeRight->LandscapeLeft,0时给4个按钮设置一个关键帧,但并不做任何操作。在1秒时对TopLeftButton和LandscapeRight设置Transform“+”选项卡里的Y设置为371,同时设置旋转度为720,(在+后面的选项卡里设置)。BottomLeftButton和BottomRightButton的Transform里Y设置为-371,旋转也设置720。

再添加一个LandscapeRight->Portrait,在1秒时给四个按钮添加一个关键帧,但不做任何操作,再在0秒时添加一个关键帧,设置Transform属性(LT,LR,BL,BR)为(X240,Y660,Y-660,X-240)

在添加一个*->LandscapeRight,操作和Portrait->LandscapeRight完全一样,为什么添加这一帧那?因为当我们首次进入这个页面时,状态是停留在Base时,Base和Portrait是一样的显示效果的,只有当我们更换横竖屏时才会进入LandscapeRight或者LandscapeLeft这时不会执行我们的动画,并且再这之后是不会再次回到Base状态,至于为什么,你要问微软的设计者了。

3.这个步骤和2是完全一样的,只不过设置的值会改变,我就不赘述了。

4.我们可以简单的测试下效果,保存回到Visual Studio中,在cs文件写如下面代码

View Code
 1         protected override void OnOrientationChanged(OrientationChangedEventArgs e)
 2         {
 3             base.OnOrientationChanged(e);
 4             switch (e.Orientation)
 5             {
 6                 case PageOrientation.Portrait:
 7                 case PageOrientation.PortraitDown:
 8                 case PageOrientation.PortraitUp:
 9                     VisualStateManager.GoToState(nCtrl, "Portrait", true);
10                     break;
11                 case PageOrientation.LandscapeLeft:
12                     VisualStateManager.GoToState(nCtrl, "LandscapeLeft", true);
13                     break;
14                 case PageOrientation.LandscapeRight:
15                     VisualStateManager.GoToState(nCtrl, "LandscapeRight", true);
16                     break;
17                 case PageOrientation.Landscape:
18                     break;
19             }
20         }

就可以运行看到效果了,和上面的效果图是一样的,不过到这里并没有结束。我们要做最后的一个事件绑定。

三、先把步骤二下的4添加的代码删掉。新建一个文件OrientationActive.cs。加入下面代码

View Code
 1 using Microsoft.Phone.Controls;
 2 using System.Windows.Interactivity;
 3 using System.Windows;
 4 
 5 namespace PhoneApp1
 6 {
 7     public class OrientationActive : TriggerAction<PhoneApplicationPage>
 8     {
 9         #region -- 自定义依赖属性 --
10         public static readonly DependencyProperty LandscapeLeftStateNameProperty =
11             DependencyProperty.Register("LandscapeLeftStateName", typeof(string), typeof(OrientationActive), new PropertyMetadata("LandscapeLeft"));
12         public string LandscapeLeftStateName 
13         {
14             get { return (string)GetValue(LandscapeLeftStateNameProperty); }
15             set { SetValue(LandscapeLeftStateNameProperty, value); }
16         }
17 
18         public static readonly DependencyProperty LandscapeRightStateNameProperty =
19             DependencyProperty.Register("LandscapeRightStateName", typeof(string), typeof(OrientationActive), new PropertyMetadata("LandscapeRight"));
20         public string LandscapeRightStateName
21         {
22             get { return (string)GetValue(LandscapeRightStateNameProperty); }
23             set { SetValue(LandscapeRightStateNameProperty, value); }
24         }
25 
26         public static readonly DependencyProperty PortraitRightStateNameProperty =
27             DependencyProperty.Register("PortraitRightStateName", typeof(string), typeof(OrientationActive), new PropertyMetadata("Portrait"));
28         public string PortraitRightStateName
29         {
30             get { return (string)GetValue(PortraitRightStateNameProperty); }
31             set { SetValue(PortraitRightStateNameProperty, value); }
32         }
33         #endregion
34 
35         protected override void Invoke(object parameter)
36         {
37             var nCtrl = this.AssociatedObject;
38             var NewOrientation = (parameter as OrientationChangedEventArgs).Orientation;
39 
40             switch (NewOrientation)
41             {
42                 case PageOrientation.Portrait:
43                 case PageOrientation.PortraitDown:
44                 case PageOrientation.PortraitUp:
45                     VisualStateManager.GoToState(nCtrl, "Portrait", true);
46                     break;
47                 case PageOrientation.LandscapeLeft:
48                     VisualStateManager.GoToState(nCtrl, "LandscapeLeft", true);
49                     break;
50                 case PageOrientation.LandscapeRight:
51                     VisualStateManager.GoToState(nCtrl, "LandscapeRight", true);
52                     break;
53                 case PageOrientation.Landscape:
54                     break;
55             }
56         }
57     }
58 }

最要是添加了3个自定义依赖属性,并重写了Invoke,目的是为绑定OnOrientationChanged事件做准备。
写好这个文件,我们再次打开blend在Assets中的Behaciours找到我们定义的行为OrientationActive,并把它拖到Objects and timeline下phoneAppcationPage节点上,这时在右边的Properties中把EventName属性选择为OnOrientationChanged,保存,回到Visual Studio。到此算是大功告成了,我们可以运行看看。并回去好好研究下Blend生成的代码,这个是很有意义的。

本问的源码:https://files.cnblogs.com/qq278360339/PhoneApp1.zip

原文地址:https://www.cnblogs.com/qq278360339/p/2516929.html