This article describes how to combine the pivot control with the content that elegantly slides into the View list. This special effect simulates the animation of the Windows Phone 7 email application.
The User Interface of Windows Phone 7 is based on Metro Design Language. Metro Design Language tends to be in a clear print format, surpassing Google's browser content and a simple method. If you want to see the practical application of Metro design, I strongly suggest you browse Scott Barnes's blog on riagenic.
I would like to mention it to you. Recently, we have launched a "watching Europe, sharing music-WP summer mobilization" event. We have taken advantage of wp7 mobile phones.
Of course, if you have an APP for the original wp7, you can also directly participate in the Windows Phone original APP talents competition, have the opportunity to get the lumia mobile Phone, and also promote your APP through the halogen noodle network.
If you did not watch the European Cup yesterday, you can guess the results of today's competition at the speed. "Hot quiz: 11th vs. Croatia VS Spain and Italy VS Ireland", you can guess the prize!
The Silverlight software provides a basic Metro form for basic elements of WP 7 (such as buttons and boxes) and several special control systems for the receiver, such as lens and Panorama. this control system makes it easier to create a basic Metro interface. Here I suggest you go to Scott Barnes's blog again. Not all Metro is about black and white! However, when you use a WP7 phone, you may notice that the applications that come with them are emails, maps, and more functions are configured, turn off the screen when the list enters the field of view smoothly or when an option is selected. Metro is not just a static form, but also in motion.
The code in this article implements the beautiful slide effect of the local program of WP7, as shown below, moving from one option list to another with a pivot point. This code has been tested on real phone hardware.
Use this code to set the additional property ListAnimation. isw.tanimated to accurately include ListBox (or ItemsControl) in javastitem. Then apply ListAnimation and AnimationLevel to any element that you want to draw a vivid image list into the line of sight. This latency is described horizontally before each element is dynamic. For example, the validation below makes the summary slide out of the title, and of course there is a later date.
<controls:PivotItem Header="BBC News"> <!-- animating an ListBox --> <ListBox x:Name="bbcNews" local:ListAnimation.IsPivotAnimated="True"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Vertical"> <TextBlock Text="{Binding Title}" Style="{StaticResource PhoneTextLargeStyle}"/> <TextBlock Text="{Binding Summary}" Style="{StaticResource PhoneTextSmallStyle}" local:ListAnimation.AnimationLevel="1"/> <TextBlock Text="{Binding Date}" Style="{StaticResource PhoneTextSmallStyle}" local:ListAnimation.AnimationLevel="2"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox></controls:PivotItem>
The code to achieve this goal is relatively simple, so I will demonstrate these multi-in-One trends (delete all frequently-used formula code with additional performance)
// handles changes in the IsPivotAnimated attached propertyprivate static void OnIsPivotAnimatedChanged(DependencyObject d, DependencyPropertyChangedEventArgs args){ ItemsControl list = d as ItemsControl; list.Loaded += (s2, e2) => { // locate the pivot control that this list is within Pivot pivot = list.Ancestors<Pivot>().Single() as Pivot; // and its index within the pivot int pivotIndex = pivot.Items.IndexOf(list.Ancestors<PivotItem>().Single()); bool selectionChanged = false; pivot.SelectionChanged += (s3, e3) => { selectionChanged = true; }; // handle manipulation events which occur when the user // moves between pivot items pivot.ManipulationCompleted += (s, e) => { if (!selectionChanged) return; selectionChanged = false; if (pivotIndex != pivot.SelectedIndex) return; // determine which direction this tab will be scrolling in from bool fromRight = e.TotalManipulation.Translation.X <= 0; // locate the stack panel that hosts the items VirtualizingStackPanel vsp = list.Descendants<VirtualizingStackPanel>().First() as VirtualizingStackPanel; // iterate over each of the items in view int firstVisibleItem = (int)vsp.VerticalOffset; int visibleItemCount = (int)vsp.ViewportHeight; for (int index = firstVisibleItem; index <= firstVisibleItem + visibleItemCount; index++) { // find all the item that have the AnimationLevel attached property set var lbi = list.ItemContainerGenerator.ContainerFromIndex(index); if (lbi == null) continue; vsp.Dispatcher.BeginInvoke(() => { var animationTargets = lbi.Descendants() .Where(p => ListAnimation.GetAnimationLevel(p) > -1); foreach (FrameworkElement target in animationTargets) { // trigger the required animation GetAnimation(target, fromRight).Begin(); } }); }; }; };}
When IsPivotAnimated is first appended, The LINQ-to-VisualTree is used to lock the other half of the inittcontrol to control the SelectionChanged project. However, this is where things become more subtle! If the control of a central point only contains two titems, one selected transformation is not enough to determine whether the center point is slide to the left or right! Therefore, we need to control the ManpulationCompleted project enabled after SleletionChanged to determine the direction of movement.
Once this is done, we can repeat all projects in the list. We can assume that this project is hosted in the VirtualizingStackPanel for ListBox. Each project is visible, and another LINQ query is used to find any additional feature that sets the AnimationLevel. For each element, this animation can be created or canceled.
Dispatcher, BeginInvoke is used to start each group of animations to reduce the impact of starting 10-20 animations at the same time. If Dispatcher is not used, a very small but obvious trembling slide over the center side when testing on real hardware, this center controls whether the animation is canceled. Dispatcher, BeginInvoke's Application means that the construction and startup of the animation are now combined by every element in the list as a separate task. This means that they do not have to perform this as an independent task, allowing the mobile phone to start several animations and complete other tasks. The result of this network is that the compaction control still slides smoothly between titems.
The code for creating necessary animations is below. They simply add a TranslateTransform to these elements and create the necessary animations.
/// <summary>/// Creates a TranslateTransform and associates/// it with the given element, returning/// a Storyboard which will animate/// the TranslateTransform with a SineEase function/// </summary>private static Storyboard GetAnimation( FrameworkElement element, bool fromRight){ double from = fromRight ? 80 : -80; Storyboard sb; double delay = (ListAnimation.GetAnimationLevel(element)) * 0.1 + 0.1; TranslateTransform trans = new TranslateTransform() { X = from }; element.RenderTransform = trans; sb = new Storyboard(); sb.BeginTime = TimeSpan.FromSeconds(delay); DoubleAnimation db = new DoubleAnimation(); db.To = 0; db.From = from; db.EasingFunction = new SineEase(); sb.Duration = db.Duration = TimeSpan.FromSeconds(0.8); sb.Children.Add(db); Storyboard.SetTarget(db, trans); Storyboard.SetTargetProperty(db, new PropertyPath("X")); return sb;}
Interestingly, I tried to use Artefact Animator, which has a very concise API for creating animations in post code. however, it directly sets the performance to make every element dynamic. It is not very practical with WP7, and it can execute scripts on composition thread to improve the performance.
You can download all the code resources in listanimation.zip.
For more information, see
Http://www.codeproject.com/Articles/197753/Metro-in-Motion-Part-1-Fluid-List-Animation