zoukankan      html  css  js  c++  java
  • 【WP开发】实现Pivot控件单个PivotItem的全屏化

    在新浪微博WP7版中有一个蛮酷的特效,就是滑动list的时候直接全屏化界面。
            一直想实现这个特效,最终还是类似的实现了这个特效。

    7cc05e2a-a2db-3872-a3ab-71bf0f1e9000.jpg

    对于ApplicationBar还是很好解决的,直接对IsVisible属性设置为false就能实现,而对上面的Header进行进行隐藏就可以了,经过一番实验貌似用Margin设为负数就能够解决。

    好接下去看代码:
    首先是布局文件。


    1. <controls:Pivot x:Name="FeaturePivot" Title="{Binding Title}" Foreground="{StaticResource PhoneAccentBrush}">
    2.             <controls:PivotItem x:Name="StoryPivotItem">
    3.                 <controls:PivotItem.Header>
    4.                     <TextBlock Text="{Binding Storys.Title}" FontSize="64" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,10,0,0" Foreground="{StaticResource PhoneAccentBrush}"></TextBlock>
    5.                 </controls:PivotItem.Header>
    6.                 <lw:StoryList x:Name="HomeTimeLine" DataContext="{Binding Storys}" />
    7.             </controls:PivotItem>
    8. </controls:Pivot>
    复制代码


    这里的lw:StoryList是一个UserControl,里面是一个List和ListItem的模版文本,这里不用去管它。但后面它困扰了我很久。
    好,由于这是扩展的交互方式,我们可以不用严格的把BackCode写在ViewModel里,我们就直接写在xaml.cs里就行了。


    1.         void FullScreenAction()
    2.         {
    3.             if (this.ApplicationBar.IsVisible == false)
    4.                 return;
    5.             this.FeaturePivot.Margin = new Thickness(0, -158, 0, 0);
    6.             this.GlobalProgressBar.Margin = new Thickness(0);
    7.             this.ApplicationBar.IsVisible = false;
    8.             this.BackKeyPress += OnFullScreenBackKeyPress;
    9.         }
    10.         void StopFullScreenAction()
    11.         {
    12.             if (this.ApplicationBar.IsVisible == true)
    13.                 return;
    14.             this.GlobalProgressBar.Margin = new Thickness(80, 32, 120, 0);
    15.             this.ApplicationBar.IsVisible = true;
    16.             this.FeaturePivot.Margin = new Thickness(0);
    17.             this.BackKeyPress -= OnFullScreenBackKeyPress;
    18.         }
    19.         private void OnFullScreenBackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
    20.         {
    21.             StopFullScreenAction();
    22.             e.Cancel = true;
    23.         }
    复制代码


    这是最挫的实现方式,直接this.FeaturePivot.Margin = new Thickness(0, -158, 0, 0);设置Margin为负值,能达到全屏的效果,但直接隐藏header用户体验很不好。并且这个时候还是能够左右滑动
    PS:这里需要注意按后退键是能够退出全屏的,并在退出时清空BackKeyPress这个Event,防止阻碍用户正常退出App。

    事情一件一件来,先解决左右滑动的问题。toolkit中有一个控件叫lockablePivot,在这里它就可以用了。

    将上面的xml代码中的controls:Pivot替换成toolkit:LockablePivot,其他不用变,在backcode中再放入一些代码:


    1. void FullScreenAction()
    2.         {
    3.             if (this.ApplicationBar.IsVisible == false)
    4.                 return;
    5.             this.FeaturePivot.Margin = new Thickness(0, -158, 0, 0);
    6.             this.GlobalProgressBar.Margin = new Thickness(0);
    7.             this.ApplicationBar.IsVisible = false;
    8.             this.FeaturePivot.IsLocked = true; //added code
    9.             this.BackKeyPress += OnFullScreenBackKeyPress;
    10.         }
    11.         void StopFullScreenAction()
    12.         {
    13.             if (this.ApplicationBar.IsVisible == true)
    14.                 return;
    15.             this.GlobalProgressBar.Margin = new Thickness(80, 32, 120, 0);
    16.             this.ApplicationBar.IsVisible = true;
    17.             this.FeaturePivot.Margin = new Thickness(0);
    18.             this.FeaturePivot.IsLocked = false; //added code
    19.             this.BackKeyPress -= OnFullScreenBackKeyPress;
    20.         }
    21.         private void OnFullScreenBackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
    22.         {
    23.             StopFullScreenAction();
    24.             e.Cancel = true;
    25.         }
    复制代码

    只是增加this.FeaturePivot.IsLocked的定值操作就能完美的解决全屏时能滑动的现象。


    接下来,貌似得加点动画才感觉有较好的用户体验,好,继续,我们会对上面的代码继续优化。

    到加动画的时候又犯难了,尼玛查文档发现Storyboard根本不支持Margin属性的DoubleAnimation类型的动画,因为Margin在SL中被定义成一个Object,而DoubleAnimation只能对数值类进行补间动画。
    不过还是有方案的,就是用RenderTransform下的CompositeTransform的Translate系列属性。

    直接看代码。


    1. <phone:PhoneApplicationPage.Resources>
    2.         <Storyboard x:Name="TitleDispear">
    3.             <DoubleAnimation Duration="0:0:1" To="-158" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
    4.             Storyboard.TargetName="FeaturePivot" d:IsOptimized="True">
    5.                 <DoubleAnimation.EasingFunction>
    6.                     <CubicEase EasingMode="EaseOut" />
    7.                 </DoubleAnimation.EasingFunction>
    8.             </DoubleAnimation>
    9.         </Storyboard>
    10.         <Storyboard x:Name="TitleAppear">
    11.             <DoubleAnimation Duration="0:0:1" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
    12.             Storyboard.TargetName="FeaturePivot" d:IsOptimized="True">
    13.                 <DoubleAnimation.EasingFunction>
    14.                     <CubicEase EasingMode="EaseOut" />
    15.                 </DoubleAnimation.EasingFunction>
    16.             </DoubleAnimation>
    17.         </Storyboard>
    18. </phone:PhoneApplicationPage.Resources>
    19. <!---------------code---------------->
    20. <toolkit:LockablePivot x:Name="FeaturePivot" Title="{Binding Title}" Foreground="{StaticResource PhoneAccentBrush}">
    21.             <toolkit:LockablePivot.RenderTransform>
    22.                 <CompositeTransform />
    23.             </toolkit:LockablePivot.RenderTransform>
    24.             <i:Interaction.Triggers>
    25.                 <i:EventTrigger EventName="SelectionChanged">
    26.                     <cmd:EventToCommand Command="{Binding ChangeSelectionCommand}"  CommandParameter="{Binding ElementName=FeaturePivot}" />
    27.                 </i:EventTrigger>
    28.             </i:Interaction.Triggers>
    29.             <controls:PivotItem x:Name="StoryPivotItem">
    30.                 <controls:PivotItem.RenderTransform>
    31.                     <CompositeTransform />
    32.                 </controls:PivotItem.RenderTransform>
    33.                 <controls:PivotItem.Header>
    34.                     <TextBlock Text="{Binding Storys.Title}" FontSize="64" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,10,0,0" Foreground="{StaticResource PhoneAccentBrush}"></TextBlock>
    35.                 </controls:PivotItem.Header>
    36.                 <lw:StoryList x:Name="HomeTimeLine" DataContext="{Binding Storys}" />
    37.             </controls:PivotItem>
    38. <!------------code--------------->
    39. </toolkit:LockablePivot>
    复制代码

    在上面的XML文件中定义了两个Storyboard动画资源,全屏化时让FeaturePivot的TranslateY由0->-158,向上溢出,这样就是实现了header的隐藏,所以TranslateY和margin都是可以隐藏header的,但有一点很大的不同,

    TranslateY不会改变UIElement的大小,而Margin会改变,负数等于是拉伸大小。于是这里问题就产生了,如果光设置TranslateY会导致整个Pivot下方有一部分空白区域。。。所以要着手解决这个问题,也就是这个问题困然了我很久。。。。

    看backcode代码:

    1.         void FullScreenAction()
    2.         {
    3.             if (this.ApplicationBar.IsVisible == false)
    4.                 return;
    5.             this.FeaturePivot.Margin = new Thickness(0, 0, 0, -158);
    6.             this.GlobalProgressBar.Margin = new Thickness(0);
    7.             TitleDispear.Begin();
    8.             this.ApplicationBar.IsVisible = false;
    9.             this.FeaturePivot.IsLocked = true;
    10.             this.BackKeyPress += OnFullScreenBackKeyPress;
    11.         }
    12.         void StopFullScreenAction()
    13.         {
    14.             if (this.ApplicationBar.IsVisible == true)
    15.                 return;
    16.             this.GlobalProgressBar.Margin = new Thickness(80, 32, 120, 0);
    17.             this.ApplicationBar.IsVisible = true;
    18.             TitleAppear.Begin();
    19.             this.FeaturePivot.Margin = new Thickness(0);
    20.             this.FeaturePivot.IsLocked = false;
    21.             this.BackKeyPress -= OnFullScreenBackKeyPress;
    22.         } //code
    复制代码



    这里我们再start时先对Pivot的Margin的bottom设置为-158,用户这时候其实是感知不到pivot的大小变化的,因为溢出的看不到,接下来在进行动画的begin操作。就能完美的实现全屏模式了。

    慢着,如何触发全屏这个动作呢,新浪是这么做的:用户快速下滑List的时候会开启,而上拉时关闭。接下来得加上手势。

    我们要用到toolkit中的GestureService行为了。

    前端代码:


    1.           <controls:PivotItem x:Name="StoryPivotItem">
    2.                 <controls:PivotItem.RenderTransform>
    3.                     <CompositeTransform />
    4.                 </controls:PivotItem.RenderTransform>
    5.                 <controls:PivotItem.Header>
    6.                     <TextBlock Text="{Binding Storys.Title}" FontSize="64" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,10,0,0" Foreground="{StaticResource PhoneAccentBrush}"></TextBlock>
    7.                 </controls:PivotItem.Header>
    8. <!-- 增加下面的语句 -->
    9.                 <toolkit:GestureService.GestureListener>
    10.                     <toolkit:GestureListener Flick="OnStoryGestureListenerFlick"/>
    11.                 </toolkit:GestureService.GestureListener>
    12. <!-- END -->
    13.                 <lw:StoryList x:Name="HomeTimeLine" DataContext="{Binding Storys}" />
    14.             </controls:PivotItem>
    复制代码



    BackCode:


    1.         private void OnStoryGestureListenerFlick(object sender, FlickGestureEventArgs e)
    2.         {
    3.             if (SettingsHelper.GetFullScreenMode() == "0")
    4.                 return;
    5.             if (e.Direction == System.Windows.Controls.Orientation.Horizontal) //判断手势方向
    6.                 return;
    7.             //if (e.Angle < 260 || e.Angle > 280) //角度判断,可以不用
    8.             //    return;
    9.             if (e.VerticalVelocity < 0) //垂直速度判断
    10.             {
    11.                 FullScreenAction();
    12.             }
    13.             else
    14.             {
    15.                 StopFullScreenAction();
    16.             }
    17.         }
    复制代码


    在前端中加入上面的语句来声明一个手势bind,在backcode中进行ActionBind,SettingsHelper.GetFullScreenMode()是设置信息,默认是开启的。
    其他的看注释。

    好,这样就差不多实现了新浪微博类似的全屏模式。。。出个效果图(顺便宣传一下来往~~,哇咔咔)

    普通界面:

    aaa8278a-adcc-3f03-9d88-80f8e777cc10.png


    换肤加全屏界面:

    70b57882-a02e-3260-8502-7dc169356853.png




    Hummm,尼玛还是全屏神马的才能看得更多嘛!!

    http://www.itboat.net/thread-38914-1-1.html


     

  • 相关阅读:
    8.22
    webstrom安装流程
    8.21
    8.20
    8.20学习笔记
    使用WebClient异步获取http资源
    导航栏,可直接使用
    asp.net mvc5实现单点登录
    使用C#调用Word的接口生成doc文件与html文件
    下载网页并保存
  • 原文地址:https://www.cnblogs.com/zziss/p/2782691.html
Copyright © 2011-2022 走看看