UWP: Use Behavior to implement FlipView simple scaling effect, uwpflipview

Source: Internet
Author: User

UWP: Use Behavior to implement FlipView simple scaling effect, uwpflipview

First

First install the Behavior SDK: Search and install Microsoft. Xaml. Behaviors. Uwp. Managed in Nuget.

Create a new class, AnimationFlipViewBehavior. cs, and inherit the DependencyObject and IBehavior interfaces:

namespace TestBehavior{    public class AnimationFlipViewBehavior: DependencyObject, IBehavior    {        public DependencyObject AssociatedObject { get; set; }        public void Attach(DependencyObject associatedObject)        {            AssociatedObject  = associatedObject;        }        public void Detach()        {        }    }}

Attach is the method called when Behavior is added, and Detach is the method called when Behavior is removed.

In this case, the Attach command is used to determine whether it is FlipView and save it. Then obtain ScrollViewer as usual. If FlipView has been Loaded, you can directly obtain ScrollViewer. Otherwise, you must obtain the ScrollViewer In the Loaded event of FlipView.

1 FlipView flipView; 2 ScrollViewer scrollViewer; 3 Compositor compositor; 4 CompositionPropertySet scrollPropSet; 5 6 public DependencyObject dependencies {get; private set;} 7 8 public void Attach (DependencyObject dependencies) 9 {10 AssociatedObject = associatedObject; 11 if (associatedObject is FlipView flip) flipView = flip; 12 else throw new ArgumentException ("object not FlipView"); 13 scrollViewer = Helper. findVisualChild <ScrollViewer> (flipView, "ScrollingHost"); 14 if (scrollViewer = null) 15 {16 flipView. loaded + = FlipView_Loaded; 17} 18 else InitCompositionResources (scrollViewer); 19} 20 21 private void FlipView_Loaded (object sender, RoutedEventArgs e) 22 {23 flipView. loaded-= FlipView_Loaded; 24 var scroll = Helper. findVisualChild <ScrollViewer> (flipView, "ScrollingHost"); 25 if (scroll = null) throw new ArgumentNullException ("ScrollViewer blank"); 26 else scrollViewer = scroll; 27 28 InitCompositionResources (scrollViewer); 29} 30 31 void InitCompositionResources (ScrollViewer scroll) 32 {33 if (compositor = null) compositor = ElementCompositionPreview. getElementVisual (flipView ). compositor; 34 if (scroll = null) return; 35 36 scrollPropSet = ElementCompositionPreview. getScrollViewerManipulationPropertySet (scrollViewer); 37}
View Code
 1 public static class Helper 2 { 3     public static T FindVisualChild<T>(DependencyObject obj, int Index = 0) where T : DependencyObject 4     { 5         if (Index == -1) return null; 6         int count = VisualTreeHelper.GetChildrenCount(obj); 7         int findedcount = 0; 8         for (int i = 0; i < count; i++) 9         {10             DependencyObject child = Windows.UI.Xaml.Media.VisualTreeHelper.GetChild(obj, i);11             if (child != null && child is T)12             {13                 if (findedcount == Index)14                     return (T)child;15                 else16                 {17                     findedcount++;18                 }19             }20             else21             {22                 T childOfChild = FindVisualChild<T>(child, findedcount);23                 if (childOfChild != null)24                     return childOfChild;25             }26         }27         return null;28     }29     public static T FindVisualChild<T>(DependencyObject obj, string name) where T : DependencyObject30     {31         int count = VisualTreeHelper.GetChildrenCount(obj);32         int findedcount = 0;33         for (int i = 0; i < count; i++)34         {35             DependencyObject child = Windows.UI.Xaml.Media.VisualTreeHelper.GetChild(obj, i);36             if (child != null && child is T)37             {38                 if ((child as FrameworkElement).Name == name)39                     return (T)child;40                 else41                 {42                     findedcount++;43                 }44             }45             else46             {47                 T childOfChild = FindVisualChild<T>(child, findedcount);48                 if (childOfChild != null)49                     return childOfChild;50             }51         }52         return null;53     }54 }
View Code

Then, create two expression animations for the center point and scaling.

ExpressionAnimation CenterPointAnimation;ExpressionAnimation ScaleAnimation;void InitCompositionResources(ScrollViewer scroll){    if (compositor == null) compositor = ElementCompositionPreview.GetElementVisual(flipView).Compositor;    if (scroll == null) return;    scrollPropSet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollViewer);    if (CenterPointAnimation == null)    {        CenterPointAnimation = compositor.CreateExpressionAnimation("Vector3(visual.Size.X/2,visual.Size.Y/2,0)");    }    if (ScaleAnimation == null)    {        ScaleAnimation = compositor.CreateExpressionAnimation("Clamp(1- (visual.Offset.X + scroll.Translation.X) / visual.Size.X * 0.4, 0f, 1f)");        ScaleAnimation.SetReferenceParameter("scroll", scrollPropSet);    }}

Here we will focus on ScaleAnimation.

Clamp (value, min, max) in the expression is a built-in function. value is returned when the value is between min and max. If the value is smaller than min, min is returned. If the value is greater than max, max is returned.

FlipView is a ScrollViewer with horizontal scrolling. The Visual. Offset. X of the elements in ScrollViewer controls the position of the Visual instead of 0 by default. Therefore, you only need to judge the relationship between visual. Offset. X and scroll. Translation. X, and then you can make a motion picture.

Then, write a method to attach these animations to all Items containers.

Because the default Items is not Observable, there are two solutions. One is to set ItemsSource as an ObservableCollection and then register the CollectionChanged event. This will increase the coupling between the control and the page background code. For a cleaner code structure, we use a method with lower performance to register the SelectionChanged event of FlipView and call the InitAnimation method here.

If only the SelectedItem and the Left and Right items are appended with an animation each time, the PC test will be perfect, but the animation will not be loaded on the mobile phone, or during touch operations. This involves a big pitfall of FlipView and layout.

When the mouse and code operation SelectedIndex switches to the page, the SelectionChanged event is triggered before the animation is played. However, only when you slide the screen and send it to your hand can the system know whether to switch the page. Therefore, each time we play the animation with our hands and trigger SelectionChanged, the animation will not be appended to the next Item, so every time we add an animation to all items, although some performance is lost, it can be ensured that the problem does not occur.

 1 void InitAnimation() 2 { 3     if (compositor != null) 4     { 5         for (int i = 0; i < flipView.Items.Count; i++) 6         { 7             var item = flipView.ContainerFromIndex(i); 8             if (item is UIElement ele) 9             {10                 var visual = ElementCompositionPreview.GetElementVisual(ele);11                 CenterPointAnimation.SetReferenceParameter("visual", visual);12                 visual.StartAnimation("CenterPoint", CenterPointAnimation);13                 visual.StopAnimation("Scale.X");14                 visual.StopAnimation("Scale.Y");15                 ScaleAnimation.SetReferenceParameter("visual", visual);16                 visual.StartAnimation("Scale.X", ScaleAnimation);17                 visual.StartAnimation("Scale.Y", ScaleAnimation);18             }19         }20     }21 }

 

Finally, the last call of InitAnimation in Loaded is completed.

Source code download

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.