为ListBox中的列表项添加加载动画
2014-09-10 15:53
246 查看
static public class ListAnimationsHelper { public static bool GetIsPivotAnimated(DependencyObject obj) { return (bool)obj.GetValue(IsPivotAnimatedProperty); } public static void SetIsPivotAnimated(DependencyObject obj, bool value) { obj.SetValue(IsPivotAnimatedProperty, value); } // Using a DependencyProperty as the backing store for IsPivotAnimated. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsPivotAnimatedProperty = DependencyProperty.RegisterAttached("IsPivotAnimated", typeof(bool), typeof(ListAnimationsHelper), new PropertyMetadata(false, OnIsPivotAnimatedPropertyChangedCallback)); private static void OnIsPivotAnimatedPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { //初始化动画相关对象事件 ItemsControl list = d as ItemsControl; //ListBox继承于ItemsControl list.Loaded += (s2, e2) => { Pivot pivot = GetParent<Pivot>(list); int pivotIndex = pivot.Items.IndexOf(GetParent<PivotItem>(list)); //订阅Pivot控件的SelectionChanged事件, 发生SelectionChanged事件时候要触发动画 pivot.SelectionChanged += (s3, e3) => { //如果不是该列表控件对应的Pivot控件页签就不触发动画的逻辑,因为SelectionChagned事件会被多次触发 if (pivotIndex != pivot.SelectedIndex) return; var items = list.GetItemsInView().ToList(); AddSlideAnimation(items); }; var items2 = list.GetItemsInView().ToList(); AddSlideAnimation(items2); }; } public static IEnumerable<FrameworkElement> GetItemsInView(this ItemsControl itemsControl) { VirtualizingStackPanel vsp = GetChild<VirtualizingStackPanel>(itemsControl); int firstVisibleItem = (int)vsp.VerticalOffset; int visibleItemCount = (int)vsp.ViewportHeight; for (int index = firstVisibleItem; index <= firstVisibleItem + visibleItemCount + 1; index++) { var item = itemsControl.ItemContainerGenerator.ContainerFromIndex(index); if (item == null) continue; yield return item as FrameworkElement; } } private static void AddSlideAnimation(List<FrameworkElement> items) { for (int index = 0; index < items.Count; index++) { var lbi = items[index]; var animationTargets = lbi.Descendants().Where(p => ListAnimationsHelper.GetAnimationLevel(p) > -1); foreach (FrameworkElement item in animationTargets) { GetSlideAnimation(item, false).Begin(); } } } public static int GetAnimationLevel(DependencyObject obj) { return (int)obj.GetValue(AnimationLevelProperty); } public static void SetAnimationLevel(DependencyObject obj, int value) { obj.SetValue(AnimationLevelProperty, value); } // Using a DependencyProperty as the backing store for AnimationLevel. This enables animation, styling, binding, etc... public static readonly DependencyProperty AnimationLevelProperty = DependencyProperty.RegisterAttached("AnimationLevel", typeof(int), typeof(ListAnimationsHelper), new PropertyMetadata(null)); #region 操作可视化树 public static T GetParent<T>(DependencyObject item) where T:class { DependencyObject obj = VisualTreeHelper.GetParent(item); while (obj != null) { if (obj is T) return obj as T; obj = VisualTreeHelper.GetParent(obj); } return null; } public static T GetChild<T>(DependencyObject item) where T : class { var queue = new Queue<DependencyObject>(); queue.Enqueue(item); while (queue.Count > 0) { DependencyObject current = queue.Dequeue(); for (int i = VisualTreeHelper.GetChildrenCount(current) - 1; 0 <= i; i--) { var child = VisualTreeHelper.GetChild(current, i); var typeChild = child as T; if (typeChild != null) { return typeChild; } queue.Enqueue(child); } } return null; } public static IEnumerable<DependencyObject> Descendants(this DependencyObject item) { var queue = new Queue<DependencyObject>(); queue.Enqueue(item); while (queue.Count > 0) { DependencyObject current = queue.Dequeue(); for (int i = VisualTreeHelper.GetChildrenCount(current) - 1; 0 <= i; i--) { var child = VisualTreeHelper.GetChild(current, i); if (child != null) { yield return child; queue.Enqueue(child); } } } } #endregion private static DoubleAnimation CreateAnimation(double from, double to, double duration, string targetProperty, DependencyObject target) { var db = new DoubleAnimation(); db.To = to; db.From = from; db.EasingFunction = new SineEase(); db.Duration = TimeSpan.FromSeconds(duration); Storyboard.SetTarget(db, target); Storyboard.SetTargetProperty(db, new PropertyPath(targetProperty)); return db; } private static Storyboard GetSlideAnimation(FrameworkElement element, bool fromRight) { double from = fromRight ? 80 : -80; Storyboard sb; double delay = (ListAnimationsHelper.GetAnimationLevel(element)) * 0.1 + 0.1; TranslateTransform trans = new TranslateTransform() { X = from, }; element.RenderTransform = trans; sb = new Storyboard(); sb.BeginTime = TimeSpan.FromSeconds(delay); sb.Children.Add(CreateAnimation(from, 0, 0.8, "X", trans)); return sb; } }
相关文章推荐
- (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画
- (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画
- WP7 ListBox 列表项渐显加载动画
- (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画
- 怎么给listbox 的item 添加动画?
- AngularJs 自定义ajax服务为请求添加加载动画
- vue首页添加加载动画
- 加载RecycleView时为itemView添加一些过渡动画(一)
- 为ListBox的SelectedItem添加动画(附源码)
- iOS开发中在加载页面添加菊花动画(非第三方)
- ListView或GridView添加加载列表动画
- 怎么给listbox 的item 添加动画1?
- JS判断页面加载状态以及添加遮罩和缓冲动画
- 加载动画、提示框动态添加(普通提示框、确认提示框、消息提示框)
- 002-UIImageView和UIButton对比 UIImageView的帧动画 格式符补充 加载图片两种方式 添加删除SUBVIEW
- [Windows Phone] 为Listbox添加、删除item注入动画效果,并伴随Layout迁移动画
- ExtJs4问题笔记(一) 为treePanel 添加加载动画
- 高性能的给RecyclerView添加下拉刷新和加载更多动画,基于ItemDecoration(一)
- RecyclerView 动画 (添加、删除动画 以及 加载item 时的动画)
- ListView添加加载动画