在写 Windows phone应用性能优化(一)的时候,在 ListBox 的项加载的时候,添加了一些简单的动画。

其实在 Windows Phone 的应用中使用 Blend 设计动画是很容易的,并且在程序的交互中,增加一些动画

效果,用户会感觉用户体验非常的好,从而提升了用户对应用的印象评分。

本文的 demo 演示如何逐项的加载列表中的每一项。对于延时迭代加载列表中的项,通常会考虑使用 DispatherTimer,

但是如果设计的逻辑较多,需要的代码量会比较多,并且不好维护。这里使用 Rx(Reactive Extensions) 中的

Observable 类进行对 IObservable<T> 的创建。在 Rx 中 IObservable<T> (可观察序列)和 IObserver<T> (观察者)

是两个核心的元素,我研究了一段时间,感觉它在  .NET 平台是可以大有作为的,它的使用并不难,很多操作使用是以 LINQ

的扩展方法而使用的,重点是理解 (IObservable)的 “推”数据 和 (IEnumerable)的 “拉”数据的 数据源数据流向的不同。

以后还会继续研究的。之前翻译的有关 Rx 一篇文章

这个示例在页面中使用一个 Pivot 控件,两个 PivotItem 项都是使用 ListBox 作为模版,区别是:

1)第一个 PivotItem 项中的 ItemsPanel 模版使用默认的,在第二个 PivotItem 中

的 ListBox 中, 把 ItemsPanel 设置为了 WrapPanel,从而使 Item 可以流动布局:

 <ListBox ItemsSource="{Binding}" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Controls:WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>

2)两个 ListBox 中的 ItemTemplate 中的 StackPanel 在触发 Loaded 事件时,开始的动画不同。

MainPage 页面中 Pivot 控件的全部代码:

    <phone:Pivot SelectionChanged="Pivot_SelectionChanged">
<phone:PivotItem Header="Stack">
<ListBox ItemsSource="{Binding}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="stack" Orientation="Horizontal" Margin="10,30,0,0">
<StackPanel.Triggers>
<EventTrigger RoutedEvent="StackPanel.Loaded">
<BeginStoryboard>
<Storyboard x:Name="Storyboard1">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="-180"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="106"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationZ)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="246"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="0.4"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="0.4"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</StackPanel.Triggers>
<StackPanel.RenderTransform>
<CompositeTransform/>
</StackPanel.RenderTransform>
<StackPanel.Projection>
<PlaneProjection/>
</StackPanel.Projection>
<Image VerticalAlignment="Top" Source="{Binding Photo}" Width="150"/>
<TextBlock Text="{Binding Title}" Width="250" Foreground="Wheat" FontSize="25" Margin="10,0,0,0" TextWrapping="Wrap"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</phone:PivotItem>
<phone:PivotItem Header="Wrap">
<ListBox ItemsSource="{Binding}" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Controls:WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="stack" Orientation="Horizontal" Margin="10,30,0,0">
<StackPanel.Triggers>
<EventTrigger RoutedEvent="StackPanel.Loaded">
<BeginStoryboard>
<Storyboard x:Name="Storyboard1">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationX)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<QuarticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="stack">
<EasingDoubleKeyFrame KeyTime="0" Value="96"/>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<QuarticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</StackPanel.Triggers>
<StackPanel.Projection>
<PlaneProjection/>
</StackPanel.Projection>
<Image VerticalAlignment="Top" Source="{Binding Photo}" Width="200"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</phone:PivotItem>
</phone:Pivot>

程序的运行效果:

在 MainPage 的 C# 页面的主要代码就不贴出来了,和 Windows phone应用性能优化(一) 中的代码基本相同。

重点的代码,是当 Pivot 触发  Pivot_SelectionChanged 事件的时候,逐项加载 ObservableCollection 集合:

  private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ObservableCollection<News> NewsList2 = new ObservableCollection<News>();
this.DataContext = NewsList2; #region 实现 1
//IObservable<long> obser = Observable.Interval(TimeSpan.FromSeconds(0.3)).ObserveOnDispatcher(); //obser.Subscribe((i) =>
//{ // NewsList2.Add(NewsList[(int)i]);
//});
#endregion #region 实现 2 // 方法含义:
// GenerateWithTime(初始值, 循环条件, 传递给 Observer‘观察者’的值, 延迟时间, 迭代)
//
// 类似于 for循环:for(初始值;循环条件;迭代)
IObservable<int> source = Observable.GenerateWithTime(,
i => i < NewsList.Count,
i => i,
i => TimeSpan.FromSeconds(.),
i => i + ); // 在 Dispather 线程,每次接受 source 传递来的 i 值,即下面的 x
source.ObserveOnDispatcher().Subscribe(x =>
{
NewsList2.Add(NewsList[x]);
Debug.WriteLine(x);
}); #endregion
}

把上面的 Observable.GenerateWithTime(...); 方法可以理解成:

  for (int i = ; i < count; i++)
{
// 当然,Observable 的时间延迟是在异步线程中完成的
Thread.Sleep(TimeSpan.FromSeconds(.)); // 逻辑
}

工程 demo 下载

Observable 示例之 Windows Phone 列表内项目逐个加载的更多相关文章

  1. 背水一战 Windows 10 (11) - 资源: CustomResource, ResourceDictionary, 加载外部的 ResourceDictionary 文件

    [源码下载] 背水一战 Windows 10 (11) - 资源: CustomResource, ResourceDictionary, 加载外部的 ResourceDictionary 文件 作者 ...

  2. wepy小程序实现列表分页上拉加载(2)

    第一篇:wepy小程序实现列表分页上拉加载(1) 本文接着上一篇内容: 4.优化-添加加载动画 (1)首先写加载动画的结构和样式 打开list.wpy文件 template结构代码: <temp ...

  3. wepy小程序实现列表分页上拉加载(1)

    使用wepy开发微信小程序商城第一篇:项目初始化 使用wepy开发微信小程序商城第二篇:路由配置和页面结构 列表页效果图: 1.新建列表页 (1)在pages里面新建一个list.wpy文件 初始代码 ...

  4. quartz.net 项目无法加载的问题

    最近尝试试用一下quartz.net 做任务调度用. 下载了源代码后打开解决方案发现项目无法加载.错误如下 未找到导入的项目“C:\Users\****\Desktop\Quartz.NET-2.1. ...

  5. 微信小程序开发——列表分页上拉加载封装实现(订单列表为例,订单状态改变后刷新列表滚动位置不变)

    业务需求: 业务需求是给订单列表添加分页功能,也就是上拉加载这种每次只请求加载固定数量的数据. 需求分析: 对业务来说就是简单的分页上拉加载,但是对于技术实现来说,除了要处理分页数据的累加加载,还要处 ...

  6. 模块 DLL C:\WINDOWS\system32\inetsrv\aspnetcore.dll 未能加载。返回的数据为错误信息。

    更新了win10的版本后,就启动原来的iis发布的程序 程序池就自动关闭.后来 启动网站 iis程序池自动关闭. 在为应用程序池“.NET v4.5”提供服务的工作进程“21908”中,协议“http ...

  7. 在iframe内页面完全加载完后,关闭父页面生成的div遮罩层

    遮罩层div为iframe父页面生成,需在iframe内页面完全加载完后,关闭遮罩层 alertMsgClose() :函数为关闭遮罩层函数 此段代码在iframe页面内: <script> ...

  8. Springboot项目自动加载设置

    SpringBoot是允许项目自动加载的,但是需要在pom文件映入依赖库 1.导入依赖库 <dependency> <groupId>org.springframework.b ...

  9. Windows Phone 7 ListBox 列表项渐显加载动画学习笔记

    在wp7程序中,当程序功能越来越复杂时,性能问题是我们不得不考虑的一个问题.在聊天列表中,如果聊天项过多,而且项目UI组件足够复杂时, 我们不得不想尽办法让UI尽快加载.所以有一种可行的方案,就是像Q ...

随机推荐

  1. Django的restful api自动生成工具django-rest-swagger介绍

    源码位置:https://github.com/marcgibbons/django-rest-swagger 文档位置:https://marcgibbons.com/django-rest-swa ...

  2. 数学图形(2.26) 3D曲线结

    我收集的几种曲线结 knot(huit) #http://www.mathcurve.com/courbes3d/noeuds/noeudenhuit.shtml vertices = 1000 t ...

  3. [Todo]提升电商网站性能方面的一些资料材料

    又到国庆,喷一喷12306.cn的技术架构 http://chengxu.org/p/369.html 其中用到了不少比较细节的优化技巧. 提到库存管理是电商非常难的地方.也讲了跟秒杀相关的一些内容.

  4. C#中this的作用

    一.C# this指针的几种用法 1.限定被相似的名称隐藏的成员   C# 代码   复制 public class ThisName { public string name = "张三& ...

  5. Opencv 完美配置攻略 2014 (Win8.1 + Opencv 2.4.8 + VS 2013)

    http://my.phirobot.com/blog/2014-02-opencv_configuration_in_vs.html 2012年4月给同学写了篇傻瓜式的 VS2010+Opencv- ...

  6. 【pyhon】黑客用字典暴力破解Zip文件密码原理性展示

    基本原理:用程序把字典文件里拟定好的密码一个个提取出来,去测试zip能否打开 字典文件pass.txt内容: 1224 2121 asdf abcd1234 dwsdsd dssds 程序代码: # ...

  7. leetCode 86.Partition List(分区链表) 解题思路和方法

    Given a linked list and a value x, partition it such that all nodes less than x come before nodes gr ...

  8. Jenkins 安装与使用--实例

    參考了博客Jenkins master在windows上安装 Jenkins的主要功能是监视反复工作的运行,比如软件project的构建详细地: *软件的持续构建和測试 本质上提供了一个易于使用的持续 ...

  9. 解决iOS Xcode 模拟器键盘不弹出

    1. 选中模拟器,在屏幕上方的菜单中找到Hardware->Keyboard 2. 直接快捷键shift+command+k

  10. vue mixin使用

    1.概述 将一些公用方法引入到不同的组件中. 2.引入方式 (1)全局引入 // 注册全局Mixin Vue.mixin({ methods: { $touch: function() { // 用以 ...