在WP7手机的开始屏幕,如果你Hold住某一个瓷贴,就会发现除了你按住的那个瓷贴其他全部下沉半透明,然后开始在不停地漂来漂去~~
今天来模仿一下这个效果。
新建一个项目,然后在Grid里放一个ListBox。
OK 开始编写 ListBox 的模版。
首先是ItemsPanelTemplate。
<ListBox.ItemsPanel>
         <ItemsPanelTemplate>
                 <toolkit:WrapPanel/>
         </ItemsPanelTemplate>
</ListBox.ItemsPanel>
我们放一个WrapPanel,让它进行自动排列和换行。
然后就是主要的 ItemTemplate。
 
<ListBox.ItemTemplate>
                    <DataTemplate>
                        <Canvas Width="185" Height="185">
                        <Grid x:Name="grid">
                            <Grid.RenderTransform>
                                <TranslateTransform/>
                            </Grid.RenderTransform>
                            <Grid.Resources>
                                <Storyboard x:Name="sbTranslate">
                                    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="grid"
                                           Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)">
                                            <EasingDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
                                            <EasingDoubleKeyFrame x:Name="translateX" KeyTime="00:00:1" Value="0">
                                            <EasingDoubleKeyFrame.EasingFunction>
                                                <SineEase EasingMode="EaseInOut"/>
                                            </EasingDoubleKeyFrame.EasingFunction>
                                        </EasingDoubleKeyFrame>
                                    </DoubleAnimationUsingKeyFrames>
                                    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="grid"
                                           Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)">
                                            <EasingDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
                                            <EasingDoubleKeyFrame x:Name="translateY" KeyTime="00:00:1" Value="0">
                                            <EasingDoubleKeyFrame.EasingFunction>
                                                <SineEase EasingMode="EaseInOut"/>
                                            </EasingDoubleKeyFrame.EasingFunction>
                                        </EasingDoubleKeyFrame>
                                    </DoubleAnimationUsingKeyFrames>
                                </Storyboard>
                            </Grid.Resources>
                                <Image Visibility="Collapsed" Source="/Images/StartPage_DeleteFav.png" Width="42" Height="42" HorizontalAlignment="Right" VerticalAlignment="Top" Canvas.ZIndex="1" MouseLeftButtonUp="Image_MouseLeftButtonUp" Margin="-10"/>
                                <toolkit:HubTile GroupTag="QuickLink" Notification="{Binding Notification}" Message="{Binding Message}" Title="{Binding Title}" Source="{Binding Src}" Background="{StaticResource PhoneAccentBrush}"/>
                        </Grid>
                        </Canvas>
                    </DataTemplate>
                </ListBox.ItemTemplate>
 
这里 放了一个 Grid ,里面很简单,一个 Image 用来 做 右上角删除图标。然后是一个 HubTile,简单模仿一下。
主要的是 Grid 里 写的 资源,两个 DoubleAnimationUsingKeyFrames,用来操作 TranslateTransform。
好,前台很简单。来看看后台。先为 ListBox 添加几个事件:

Loaded="listBox_Loaded" LostFocus="listBox_LostFocus" SelectionChanged="listBox_SelectionChanged"
先来写Loaded 事件:
for (int i = 0; i < listBox.Items.Count; i++)
            {
                ListBoxItem item = (ListBoxItem)listBox.ItemContainerGenerator.ContainerFromIndex(i);
                item.Hold += item_Hold;
            }
为每个listboxitem 添加 必须的 Hold 事件。
 
void item_Hold(object sender, System.Windows.Input.GestureEventArgs e)
        {
            if (!isHold)
            {
                isHold = true;
                var item = sender as ListBoxItem;
                holdItem = item;
                for (int i = 0; i < items.Count; i++)
                {
                    ListBoxItem _item = (ListBoxItem)listBox.ItemContainerGenerator.ContainerFromItem(items[i]);
                    if (_item != item)
                    {
                        Transform(1, 0.75, _item, 0.2);
                        var grid = FindVisualChild<Grid>(_item);

var sb = grid.Resources["sbTranslate"] as Storyboard;

storyList.Add(Bouncing(sb,false), grid.DataContext);
                    }
                    else
                    {
                        //显示按住item的关闭按钮
                        var img = FindVisualChild<Image>(_item);
                        img.Visibility = System.Windows.Visibility.Visible;
                    }
                }
            }
        }
 
在item_Hold事件里做了两件事:显示按住item的关闭按钮,其他item 下沉半透明,然后是启动漂动:Bouncing(sb,false);
Bouncing 这个方法,返回一个 DispatcherTimer 第一个参数是一个Storyboard,那这里放入的就是在前台为 Grid 添加的 资源里的 Storyboard。
先是找到这个 ListboxItem  里的 FindVisualChild<Grid>(_item),然后再找出他的 Storyboard。
那重点来说一下这个函数。
 
private DispatcherTimer Bouncing(Storyboard sb,bool isover)
        {
            Random random = new Random();
            DoubleKeyFrame sp0 = ((DoubleAnimationUsingKeyFrames)sb.Children[0]).KeyFrames[0];
            DoubleKeyFrame ea0 = ((DoubleAnimationUsingKeyFrames)sb.Children[0]).KeyFrames[1];
            DoubleKeyFrame sp1 = ((DoubleAnimationUsingKeyFrames)sb.Children[1]).KeyFrames[0];
            DoubleKeyFrame ea1 = ((DoubleAnimationUsingKeyFrames)sb.Children[1]).KeyFrames[1];

sp0.Value = 0;
            sp1.Value = 0;
            ea0.Value = 0;
            ea1.Value = 0;

DispatcherTimer dispatcherTimer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(0) };
            dispatcherTimer.Tick += delegate
            {
                sb.Stop();
                sp0.Value = ea0.Value;
                sp1.Value = ea1.Value;
               
                if (!isover)
                {
                    ea0.Value = random.Next(-10, 10);//随机数 X
                    ea1.Value = random.Next(-10, 10);//随机数 Y
                    sb.Begin();
                }
                dispatcherTimer.Interval = TimeSpan.FromSeconds(random.Next(9, 13) *0.1);
            };
            if (isover)
                sb.Begin();
            else
                dispatcherTimer.Start();

return dispatcherTimer;
        }
 
先是根据传入的 Storyboard 找出 它里面DoubleAnimationUsingKeyFrames的每个DoubleKeyFrame。
然后在找出每个DoubleKeyFrame的Value,并初始化。
接下来是生成一个DispatcherTimer对象,这里初始化的Interval是0,也就是立马执行下面Tick的事件,不会造成刚开始动画延迟的感觉。
在对ea0和ea1赋值,用一个随机数,范围在-10到10。也这就在这个方圆内漂动。
而上面的sp0和sp1的赋值是为了下一次动画,不是从零开始的。
下面还有一句:dispatcherTimer.Interval = TimeSpan.FromSeconds(random.Next(9, 13) *0.1);
这句是为了让每个Timer的间隔有所不同,就不会造成所有瓷贴同时漂动同时结束的统一动作。
 
OK,主要的代码都介绍完了,上图


 
还有很多功能,比如 listBox_SelectionChanged,OnBackKeyPress,StopBouncing,就不多介绍了,这里就说一下我实现的方法思路,
就是通过,调用动画通过 Timer 来控制,来实现 飘动效果。
如果有兴趣,可以继续了解我下面的 DEMO。

BouncingDemo:http://dl.dbank.com/c0upp01pv7

WP7:模拟开始屏幕Tile漂动效果的更多相关文章

  1. 手机端轻应用模拟原生的下拉刷新效果(JavaScript)

    方案一:使用iscoll等有下拉功能的框架. 分析:因为项目的结构已经基本完成,再使用框架,会与原来的结构互相影响: 方案二:用JavaScript.Jquery写. 分析:可能没有直接使用框架的效果 ...

  2. ANDROID模拟火花粒子的滑动喷射效果

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 开篇废话: 年前换了一个手机,SONY的Z3C.这个手机在解锁屏幕时有一个滑动动画,类似火 ...

  3. Android与.Net交互模拟用户屏幕操作添加APN和网络4G/3G切换

    前几天接到一个需求,我们的客户需要对手机网络接入点进行可用性测试,简单点说就是需要实现Android上的APN配置的添加,APN切换网络模式4G/3G/2G切换,我要调研下写个demo. 因为是要实现 ...

  4. WPF界面设计技巧(7)—模拟电梯升降的缓动动画

    原文:WPF界面设计技巧(7)-模拟电梯升降的缓动动画 如同Flash一样,WPF的亮点之一也在于其擅于表现平滑的动画效果,但以移动动画来说,仅凭简单的起始位置.目标位置,所产生的动画仍会非常生硬,这 ...

  5. 过渡与动画 - 缓动效果&基于贝塞尔曲线的调速函数

    难题 给过渡和动画加上缓动效果是一种常见的手法(比如具有回弹效果的过渡过程)是一种流行的表现手法,可以让界面显得更加生动和真实:在现实世界中,物体A点到B点往往也是不完全匀速的 以纯技术的角度来看,回 ...

  6. iOS开发之使用Storyboard预览UI在不同屏幕上的运行效果

    在公司做项目一直使用Storyboard,虽然有时会遇到团队合作的Storyboard冲突问题,但是对于Storyboard开发效率之高还是比较划算的.在之前的博客中也提到过,团队合作使用Storyb ...

  7. canvas弹动效果

    弹动效果,用物体与目标的距离乘上系数再累加至速度上,让物体呈加速度运动,再让速度乘与摩擦力系数,让物体最终停止运动 代码如下所示 var canvas = document.getElementByI ...

  8. javascript的缓动效果

    这部分对原先的缓动函数进行抽象化,并结合缓动公式进行强化.成品的效果非常惊人逆天.走过路过不要错过. 好了,打诨到此为止.普通的加速减速是难以让人满意的,为了实现弹簧等让人眼花缭乱的效果必须动用缓动公 ...

  9. animation js控制 缓动效果

    <!DOCTYPE html><html><head><meta charset="utf-8" /><title>缓动 ...

随机推荐

  1. Nginx+tomcat负载均衡配置

    Nginx+tomcat是目前主流的java web架构,如何让nginx+tomcat同时工作呢,也可以说如何使用nginx来反向代理tomcat后端均衡呢?直接安装配置如下: 1.JAVA JDK ...

  2. 秀尔算法:破解RSA加密的“不灭神话”

    RSA加密 VS 秀尔算法 作为RSA加密技术的终结者——“太多运算,无法读取”的秀尔算法(Shor’s algorithm)不是通过暴力破解的方式找到最终密码的,而是利用量子计算的并行性,可以快速分 ...

  3. OJ 1188 全排列---康托展开

    题目描述 求n的从小到大第m个全排列(n≤20). 输入 n和m 输出 输出第m个全排列,两个数之间有一空格. 样例输入 3 2 样例输出 1 3 2 #include<cstdio> # ...

  4. dell idrac8 部署操作系统的方法

    1,打开虚拟控制台 2,“虚拟介质”->“连接虚拟介质”->“映射虚拟介质到CD”->(选择要安装的镜像文件)->“Map device” 3, “next boot”-> ...

  5. Spring源码学习(二)AOP

    ----ProxyFactoryBean这个类,这是AOP使用的入口---- AOP有些特有的概念,如:advisor.advice和pointcut等等,使用或配置起来有点绕,让人感觉有些距离感,其 ...

  6. 应用 JD-Eclipse 插件实现 RFT 中 .class 文件的反向编译

    概述 反编译是一个将目标代码转换成源代码的过程.而目标代码是一种用语言表示的代码 , 这种语言能通过实机或虚拟机直接执行.文本所要介绍的 JD-Eclipse 是一款反编译的开源软件,它是应用于 Ec ...

  7. Balanced Binary Tree

    Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary ...

  8. C++ traits

    [本文链接] http://www.cnblogs.com/hellogiser/p/cplusplus-traits.html [分析] 什么是traits?其实它并不是一个新的概念,上个世纪90年 ...

  9. 【python】filter()

    来源:http://www.jb51.net/article/54316.htm filter函数: filter()函数可以对序列做过滤处理,就是说可以使用一个自定的函数过滤一个序列,把序列的每一项 ...

  10. javaScript中利用ActiveXObject来创建FileSystemObject操作文件

    注:如果用javascript读本地文件,遇到安全问题. 需在浏览器中进行设置,如下:     工具—> Internet选项->安全->自定义级别->启用“没有标识为安全的A ...