Windows Phone 實用開發技巧(30):Pivot切換時同時漸變背景圖片

weixin_34119545發表於2011-11-20

上篇文章講了如果動態繫結Pivot,其實繫結正確了就可以了,沒有什麼技術難點。今天介紹如果在切換PivotItem時同時漸變的切換Pivot的背景圖片,用來提高使用者體驗。

當然很多時候如果你的Pivot有背景圖片,那經常是一張圖片,不會每個PivotItem都給一張圖片。但是有時候或許就用這樣的需求,不同的Pivot有不同的背景圖片,那麼你如何去做到很好的背景圖片的切換呢?因為如果背景圖片的反差比較大的時候,給使用者的體驗不是很好。

那麼如何實現很好的過渡效果呢?我的想法是在切換時漸變其背景圖片。在剛開始使用Expression Blend的時候遇到一個問題,我們不能對Pivot的背景圖片做動畫。但是換個思路去想,我們可以對使用者控制元件的透明度做動畫,我們可以使用使用者控制元件作為當前頁面的背景動畫。

public partial class BgControl : UserControl
{
    public DependencyProperty ImageUrlProperty = DependencyProperty.Register("ImageUrl", typeof(string), typeof(BgControl), 
        new PropertyMetadata(new PropertyChangedCallback((e1,e2) =>
        {
            var control = e1 as BgControl;
            if (control != null && e2.NewValue!=null)
            {
                control.LayoutRoot.Background = new ImageBrush() { ImageSource = new BitmapImage(new Uri(e2.NewValue.ToString(), UriKind.Relative)) };
            }
        })));

    public string ImageUrl
    {
        get
        {
            return (string)base.GetValue(ImageUrlProperty);
        }
        set
        {
            base.SetValue(ImageUrlProperty, value);
        }
   }

    public BgControl()
    {
        InitializeComponent();
        Loaded += new RoutedEventHandler(BgControl_Loaded);
    }

    void BgControl_Loaded(object sender, RoutedEventArgs e)
    {
        this.LayoutRoot.Background = new ImageBrush() { ImageSource = new BitmapImage(new Uri(ImageUrl, UriKind.Relative)) };
    }
}

上述程式碼是該背景控制元件的後置程式碼,註冊了一個依賴屬性ImageUrl,在屬性發生變化的時候同時修改當前的背景。

ok,下面看看XAML中如何呼叫這個控制元件的

<Grid x:Name="LayoutRoot" Background="Transparent">
    <local:BgControl x:Name="bgControl" ImageUrl="Bg/1.jpg" />
    <controls:Pivot x:Name="pivot" Title="DYNAMIC BG" SelectionChanged="Pivot_SelectionChanged">
        <controls:PivotItem Header="pivot one">

        </controls:PivotItem>
        <controls:PivotItem Header="pivot two">

        </controls:PivotItem>
        <controls:PivotItem Header="pivot three">

        </controls:PivotItem>
    </controls:Pivot>
</Grid>

我們將該控制元件設定很Pivot平級,並且放置在Pivot的前面,這樣BgControl就會在Pivot的下方呈現。下面看看Pivot的SelectionChanged事件:

Random r = new Random();
private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    int bg = r.Next(1, 7);
    if (sb_shuffle != null)
    {
        sb_shuffle.Begin();
        pivot.IsHitTestVisible = false;
        sb_shuffle.Completed += (e1, e2) =>
        {
            bgControl.ImageUrl = string.Format("Bg/{0}.jpg", bg);
            sb_next.Begin();
            sb_next.Completed += (e3, e4) =>
                {
                    pivot.IsHitTestVisible = true;
                };
        };

    }
}

隨即生成當前背景圖片的檔名,然後播放兩個動畫,一個是當前背景的漸漸消失,一個是下一個背景的漸漸顯示。

<phone:PhoneApplicationPage.Resources>
    <Storyboard x:Name="sb_shuffle">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="bgControl">
            <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
    <Storyboard x:Name="sb_next">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="bgControl">
            <EasingDoubleKeyFrame KeyTime="0:0:1" Value="1"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
</phone:PhoneApplicationPage.Resources>

注意到SelectionChanged事件中,需要將Pivot的IsHitTestVisible設為false,即表示正在播放動畫的時候我們不能滑動Pivot,在動畫結束的時候再還原回來。

例項程式碼可以在這裡找到。Hope that helps.

相關文章