zoukankan      html  css  js  c++  java
  • Observable 示例之 Windows Phone 列表内项目逐个加载

    在写 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>
    View Code


    程序的运行效果:

    在 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(0,
              i => i < NewsList.Count,
              i => i,
              i => TimeSpan.FromSeconds(.3),
              i => i + 1);
          
          // 在 Dispather 线程,每次接受 source 传递来的 i 值,即下面的 x
          source.ObserveOnDispatcher().Subscribe(x =>
          {
              NewsList2.Add(NewsList[x]);
              Debug.WriteLine(x);
          });
    
          #endregion
      }

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

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


     

    工程 demo 下载

  • 相关阅读:
    Java学习二十九天
    Java学习二十八天
    47. Permutations II 全排列可重复版本
    46. Permutations 全排列,无重复
    subset ii 子集 有重复元素
    339. Nested List Weight Sum 339.嵌套列表权重总和
    251. Flatten 2D Vector 平铺二维矩阵
    217. Contains Duplicate数组重复元素
    209. Minimum Size Subarray Sum 结果大于等于目标的最小长度数组
    438. Find All Anagrams in a String 查找字符串中的所有Anagrams
  • 原文地址:https://www.cnblogs.com/hebeiDGL/p/3410988.html
Copyright © 2011-2022 走看看