转载

实现 WP 版微信的 Pivot Header 效果

Pivot 是 Windows Phone 最常用的一种控件,用户可以通过滑动来切换不同的视图,而切换视图的时候 PivotItem Header (默认)是会变化的——在 WP8.1 的时候是会变到第一个并且高亮显示。而 WP 微信则是采用固定的四个图标当作 Header,而这种效果并不是控件的默认属性,那么我们该怎么实现这个效果呢?

改 Header 的 Style 是一种方法,但是这里我介绍另一种方法(这篇博文用的是 WP8.1 的项目,UWP 也同样适用喔~):

去掉 PivotItem 自己的 Header ,用别的容器来装,然后通过 Pivot 的 SelectionChanged 事件来实现样式变化。

0x00 设计页面布局

这里我们把页面分成两部分,上半部分用来放 Header ,余下的部分全用来放 PivotItem ,xaml 里这样写:

<Grid>         <Grid.RowDefinitions>             <RowDefinition Height="auto"/>             <RowDefinition Height="*"/>         </Grid.RowDefinitions>         <Grid Grid.Row="0">             <!-- 这里用来放 Header -->         </Grid>         <Grid Grid.Row="1">             <!-- 这里用来放 PivotItem-->         </Grid> </Grid> 

0x01 设计 Header

先把准备好的图标加进项目里,我这里准备了四组图标,每组两个(一明一暗,其中暗的以 _ 作为文件名的结尾),我把这些图标放到 /Asset/PivotHeader/Image 里了。

实现 WP 版微信的 Pivot Header 效果

把 Header 所在那个 Grid 里等分成四列,每列一个 StackPanel ,里面放我们 Header 的图标、文字什么的。

<Grid.ColumnDefinitions>     <ColumnDefinition Width="*"/>     <ColumnDefinition Width="*"/>     <ColumnDefinition Width="*"/>     <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid Grid.Column="0">     <!-- Tapped 事件是为了让用户点击 Header 的时候也能实现切换 -->     <StackPanel Tapped="StackPanel0_Tapped" x:Name="Windows">         <!-- 先让它装入暗的图标,选中的时候再变亮,下面的同理 -->         <Image x:Name="Windows_Img" Source="ms-appx:///Assets/PivotHeaderImage/Windows_.png" Width="50" Height="50"/>         <!-- 文字的颜色也同理 -->         <TextBlock x:Name="Windows_Txt" Foreground="#CCCCCC" FontSize="15" TextAlignment="Center">Windows</TextBlock>     </StackPanel> </Grid> <Grid Grid.Column="1">     <StackPanel Tapped="StackPanel1_Tapped" x:Name="Office">         <Image x:Name="Office_Img" Source="ms-appx:///Assets/PivotHeaderImage/Office_.png" Width="50" Height="50"/>         <TextBlock x:Name="Office_Txt" Foreground="#CCCCCC" FontSize="15" TextAlignment="Center">Office</TextBlock> </StackPanel> </Grid> <Grid Grid.Column="2">     <StackPanel Tapped="StackPanel2_Tapped" x:Name="OneDrive">         <Image x:Name="OneDrive_Img" Source="ms-appx:///Assets/PivotHeaderImage/OneDrive_.png" Width="50" Height="50"/>         <TextBlock x:Name="OneDrive_Txt" Foreground="#CCCCCC" FontSize="15" TextAlignment="Center">OneDrive</TextBlock>     </StackPanel> </Grid> <Grid Grid.Column="3">     <StackPanel Tapped="StackPanel3_Tapped" x:Name="Store">         <Image x:Name="Store_Img" Source="ms-appx:///Assets/PivotHeaderImage/Store_.png" Width="50" Height="50"/>         <TextBlock x:Name="Store_Txt" Foreground="#CCCCCC" FontSize="15" TextAlignment="Center">Store</TextBlock>     </StackPanel> </Grid> 

效果是这样的:

实现 WP 版微信的 Pivot Header 效果

0x02 添加 PivotItem

准备好了 Header,下面我们要添加四个(对应四个 Header) PivotItem 了。在页面下半部分那个 Grid 里添加一个 Pivot:

<Pivot x:Name="MyPivot" SelectionChanged="MyPivot_SelectionChanged">     <PivotItem>         <Grid>             <!-- PivotItem0 -->         </Grid>     </PivotItem>     <PivotItem>         <Grid>             <!-- PivotItem1 -->         </Grid>     </PivotItem>     <PivotItem>         <Grid>             <!-- PivotItem2 -->         </Grid>     </PivotItem>     <PivotItem>         <Grid>             <!-- PivotItem3 -->         </Grid>     </PivotItem> </Pivot> 

0x03 添加切换事件

首先我们要先有一个变量,用来记录 切换前 Pivot 的 index ,所以我们先定义一个整型变量并让其初始化为 int PreIndex = 0; ;为什么要有这个变量呢,有了它之后我们就可以在切换时 直接准确 地把切换前的 Header 变成暗的,这样效率会略有提高(我猜的 -_-|||)。

然后添加 SelectionChanged 事件处理程序 MyPivot_SelectionChanged

// MyPivot 的前一个索引 int PreIndex = 0;  private void MyPivot_SelectionChanged(object sender, SelectionChangedEventArgs e) {     // 将变换前的 Header 变“暗”     switch(PreIndex)     {         case 0:             Windows_Img.Source = new BitmapImage(new Uri("ms-appx:///Assets/PivotHeaderImage/Windows_.png"));             Windows_Txt.Foreground = new SolidColorBrush(Color.FromArgb(255, 128, 128, 128));             break;         case 1:             Office_Img.Source = new BitmapImage(new Uri("ms-appx:///Assets/PivotHeaderImage/Office_.png"));             Office_Txt.Foreground = new SolidColorBrush(Color.FromArgb(255, 128, 128, 128));             break;         case 2:             OneDrive_Img.Source = new BitmapImage(new Uri("ms-appx:///Assets/PivotHeaderImage/OneDrive_.png"));             OneDrive_Txt.Foreground = new SolidColorBrush(Color.FromArgb(255, 128, 128, 128));             break;         case 3:             Store_Img.Source = new BitmapImage(new Uri("ms-appx:///Assets/PivotHeaderImage/Store_.png"));             Store_Txt.Foreground = new SolidColorBrush(Color.FromArgb(255, 128, 128, 128));             break;     }     // 当前的 Index 将会变成“切换前”的 Index      PreIndex = (sender as Pivot).SelectedIndex;      // 将当前的 Header 变“亮”     switch ((sender as Pivot).SelectedIndex)     {         case 0:             Windows_Img.Source = new BitmapImage(new Uri("ms-appx:///Assets/PivotHeaderImage/Windows.png"));             Windows_Txt.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));             break;         case 1:             Office_Img.Source = new BitmapImage(new Uri("ms-appx:///Assets/PivotHeaderImage/Office.png"));             Office_Txt.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));             break;         case 2:             OneDrive_Img.Source = new BitmapImage(new Uri("ms-appx:///Assets/PivotHeaderImage/OneDrive.png"));             OneDrive_Txt.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));             break;         case 3:             Store_Img.Source = new BitmapImage(new Uri("ms-appx:///Assets/PivotHeaderImage/Store.png"));             Store_Txt.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));             break;     } } 

别忘了添加一下 Header 的 Tapped 事件

private void StackPanel0_Tapped(object sender, TappedRoutedEventArgs e) {     MyPivot.SelectedIndex = 0; } private void StackPanel1_Tapped(object sender, TappedRoutedEventArgs e) {     MyPivot.SelectedIndex = 1; } private void StackPanel2_Tapped(object sender, TappedRoutedEventArgs e) {     MyPivot.SelectedIndex = 2; } private void StackPanel3_Tapped(object sender, TappedRoutedEventArgs e) {     MyPivot.SelectedIndex = 3; } 

好了,看一下效果吧~

实现 WP 版微信的 Pivot Header 效果

诶?Header 的图标会闪?没错,不是你的网络啊浏览器啊什么的有问题,是真的会闪!因为每次切换时都要加载图片,这样会略有延迟,可是微信的是没有闪动的,切换很流畅的!

0x04 优化!

先放张图看下优化后的效果:

实现 WP 版微信的 Pivot Header 效果

很流畅对吧(我没有对这个 gif 做手脚,是真的优化过~)。

要达到这种流畅的效果,我们需要将每组两个图标都先加载进来,怎么实现呢,用两个 StackPanel 分别装 时的 Header,不同状态显示对应的 StackPanel 就行了嘛!

那么我们需要修改一下上半部分的 Grid

<Grid Grid.Column="0">     <StackPanel Tapped="StackPanel0_Tapped" x:Name="Windows" Visibility="Collapsed">         <Image Source="ms-appx:///Assets/PivotHeaderImage/Windows.png" Width="50" Height="50"/>         <TextBlock FontSize="15" TextAlignment="Center">Windows</TextBlock>     </StackPanel>     <StackPanel Tapped="StackPanel0_Tapped" x:Name="Windows_">         <Image Source="ms-appx:///Assets/PivotHeaderImage/Windows_.png" Width="50" Height="50"/>         <TextBlock FontSize="15" TextAlignment="Center" Foreground="Gray">Windows</TextBlock>     </StackPanel> </Grid> <Grid Grid.Column="1">     <StackPanel Tapped="StackPanel1_Tapped" x:Name="Office" Visibility="Collapsed">         <Image Source="ms-appx:///Assets/PivotHeaderImage/Office.png" Width="50" Height="50"/>         <TextBlock FontSize="15" TextAlignment="Center">Office</TextBlock>     </StackPanel>     <StackPanel Tapped="StackPanel1_Tapped" x:Name="Office_">         <Image Source="ms-appx:///Assets/PivotHeaderImage/Office_.png" Width="50" Height="50"/>         <TextBlock FontSize="15" TextAlignment="Center" Foreground="Gray">Office</TextBlock>     </StackPanel> </Grid> <Grid Grid.Column="2">     <StackPanel Tapped="StackPanel2_Tapped" x:Name="OneDrive" Visibility="Collapsed">         <Image Source="ms-appx:///Assets/PivotHeaderImage/OneDrive.png" Width="50" Height="50"/>         <TextBlock FontSize="15" TextAlignment="Center">OneDrive</TextBlock>     </StackPanel>     <StackPanel Tapped="StackPanel2_Tapped" x:Name="OneDrive_">         <Image Source="ms-appx:///Assets/PivotHeaderImage/OneDrive_.png" Width="50" Height="50"/>         <TextBlock FontSize="15" TextAlignment="Center" Foreground="Gray">OneDrive</TextBlock>     </StackPanel> </Grid> <Grid Grid.Column="3">     <StackPanel Tapped="StackPanel3_Tapped" x:Name="Store" Visibility="Collapsed">         <Image Source="ms-appx:///Assets/PivotHeaderImage/Store.png" Width="50" Height="50"/>         <TextBlock FontSize="15" TextAlignment="Center"  x:Name="SPT3">Store</TextBlock>     </StackPanel>     <StackPanel Tapped="StackPanel3_Tapped" x:Name="Store_">         <Image Source="ms-appx:///Assets/PivotHeaderImage/Store_.png" Width="50" Height="50"/>         <TextBlock FontSize="15" TextAlignment="Center" Foreground="Gray">Store</TextBlock>     </StackPanel> </Grid> 

然后对应修改一下 SelectionChanged

private void MyPivot_SelectionChanged(object sender, SelectionChangedEventArgs e) {     switch(PreIndex)     {         case 0:             Windows.Visibility = Visibility.Collapsed;             Windows_.Visibility = Visibility.Visible;             break;         case 1:             Office.Visibility = Visibility.Collapsed;             Office_.Visibility = Visibility.Visible;             break;         case 2:             OneDrive.Visibility = Visibility.Collapsed;             OneDrive_.Visibility = Visibility.Visible;             break;         case 3:             Store.Visibility = Visibility.Collapsed;             Store_.Visibility = Visibility.Visible;             break;     }     PreIndex = (sender as Pivot).SelectedIndex;      switch ((sender as Pivot).SelectedIndex)     {         case 0:             Windows_.Visibility = Visibility.Collapsed;             Windows.Visibility = Visibility.Visible;             break;         case 1:             Office_.Visibility = Visibility.Collapsed;             Office.Visibility = Visibility.Visible;             break;         case 2:             OneDrive_.Visibility = Visibility.Collapsed;             OneDrive.Visibility = Visibility.Visible;             break;         case 3:             Store_.Visibility = Visibility.Collapsed;             Store.Visibility = Visibility.Visible;             break;     } } 

好了,运行一下看看吧~

前几天看 MSDN 博客侠 的文章《 Win 10 UWP开发系列:设置AppBarButton的图标 》看到一款制作图标的神器—— Merto Studio 4 ,本文用的图标就是直接从这个软件里导出来的~

原文  https://yian.me/blog/windows-phone-dev/customize-pivot-header-style.html
正文到此结束
Loading...