2017/9/19

Xamarin.Forms 教學系列文(二十五.貳)Tabbed Page


學習目標
  • TabbedPage 多頁面切換
  • Tabbed 也有 ItemSource 可以用喔!!

這也是常見的一種頁面,凡舉各種 App 都適用... 隨便一抓 Instagram 就是用 TabbedPage 為主的 App...

當你想要 App 的頁面能左滑右滑時,就該來使用 TabbedPage,

使用時要注意的就是內容要放的東西,等等範例可以看到,我們會建立起三個 ContentPage 並放入 TabbedPage 內,
除了直接放 ContentPage,我們還能將集合指派給 TabbedPage 的 ItemSource。

TabbedPage 的標題隨著內容頁 Title 屬性值而改變。

對了,iOS 的 Tab 在下方,且每個 Tab 一定要有 icon,否則無法上架 App store。

Tabbed Page

TabbedPage 衍生自 MultiPage<Page> 類別,
而 MultiPage 定義了兩個屬性讓你有能力追蹤目前的頁面:
  • CurrentPage of type T (頁面放 Page 時)
  • SelectedItem of type object (頁面放 ItemSource 時)

定義了兩個事件可讓你呼叫:
  • PagesChanged 事件,ItemSourse 改變時觸發
  • CurrentPageChanged 事件,目前頁面改變時觸發

等等的範例,我們將利用之前學過的三個範例,個別放入 TabbedPage 內:

第一個 ContentPage - 撈出些自訂義的顏色
第二個 ContentPage - 撈出來 Xamarin.forms 的顏色
第三個 ContentPaeg - 利用 Slider 改變顏色

//以上三個 ContentPage 的程式碼會附註在最後

假設這三個 ContentPage 已存在專案內,那我們來看 TabbedPage:
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:local="clr-namespace:DiscreteTabbedColors" 
             x:Class="DiscreteTabbedColors.DiscreteTabbedColorsPage">
    
    <local:BuiltInColorsPage />
    <local:NamedColorsPage />
    <local:ColorTestPage />
    
</TabbedPage>

痾... 就是這麼簡單。

執行結果:


ItemTemplate with ItemSource

這是一個 TabbedPage 的奇妙屬性,可以指派資料集合給 TabbedPage 的 ItemSource,再借由 Template 來控制畫面資料的顯示。

舉例來說,我們有一個 顏色的集合,要利用 TabbedPage 將單獨的資料顯示出來:
*OnPlatform 寫法已更改,請參考此篇文章

<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms" 
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
            xmlns:toolkit= "clr-namespace:Xamarin.FormsBook.Toolkit;assembly=Xamarin.FormsBook.Toolkit" 
            x:Class="MultiTabbedColors.MultiTabbedColorsPage"
            ItemsSource="{x:Static toolkit:NamedColor.All}">
    
    <!--注意 ItemTemplate 底下是 DataTemplate-->
    <TabbedPage.ItemTemplate>
        <DataTemplate>
            
            <!--可以再放入一個 ContentPage,但資料顯示是用 Binding 的-->
            <ContentPage Title="{Binding Name}">
                <ContentPage.Padding>
                    <OnPlatform x:TypeArguments="Thickness" 
                                iOS="0, 20, 0, 0" />
                </ContentPage.Padding>
                
                <StackLayout>
                    <Label Text="{Binding FriendlyName}" 
                           Style="{DynamicResource TitleStyle}"
                           HorizontalTextAlignment="Center" />
                    
                    <ScrollView VerticalOptions="FillAndExpand">
                        <StackLayout>
                            <BoxView Color="{Binding Color}"
                                     WidthRequest="144"
                                     HeightRequest="144"
                                     VerticalOptions="CenterAndExpand" 
                                     HorizontalOptions="Center" />
                            
                            <StackLayout VerticalOptions="CenterAndExpand" 
                                         HorizontalOptions="Center">
                                
                                <StackLayout.Resources>
                                    <ResourceDictionary>
                                        <Style TargetType="Label">
                                            <Setter Property="HorizontalTextAlignment" Value="End" />
                                        </Style>
                                    </ResourceDictionary>
                                </StackLayout.Resources>
                                
                                <Label Text="{Binding Color.R, StringFormat='Red = {0:F2}'}" />
                                <Label Text="{Binding Color.G, StringFormat='Green = {0:F2}'}" />
                                <Label Text="{Binding Color.B, StringFormat='Blue = {0:F2}'}" />
                                <Label Text="{Binding Color.A, StringFormat='Alpha = {0:F2}'}" />
                                <Label Text=" " />
                                <Label Text="{Binding Color.Hue, StringFormat='Hue = {0:F2}'}" />
                                <Label Text="{Binding Color.Saturation,StringFormat='Saturation = {0:F2}'}" />
                                <Label Text="{Binding Color.Luminosity, StringFormat='Luminosity = {0:F2}'}" />
                            </StackLayout>
                        </StackLayout>
                    </ScrollView>
                </StackLayout>
            </ContentPage>
        </DataTemplate>
    </TabbedPage.ItemTemplate>
</TabbedPage>

執行結果:

又是這個萬惡的但是

這樣的寫法在 iOS 上無法正常運作外,且 Tab 沒有任何 icon 會導致無法上架,

若要做到跨平台的話,CarouselView 會更加適合 (也是左滑右滑的一個元件),但不幸的本書還沒寫到 CarouselView 的教學...(原文就是這樣寫的...)

--------------------------------- 附錄分隔線 -----------------------------------

附錄一,撈出自訂義顏色的 ContentPage
*OnPlatform 寫法已更改,請參考此篇文章

    class BuiltInColorsPage : ContentPage
    {
        public BuiltInColorsPage()
        {
            Title = "Built-in";
            Icon = Device.OnPlatform("ic_action_computer.png", null, null);
            Padding = new Thickness(5, Device.OnPlatform(20, 5, 5), 5, 5);

            double fontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label));

            Content = new ScrollView
            {
                Content = new StackLayout
                {
                    Spacing = 0,
                    Children =
                    {
                        new Label
                        {
                            Text = "White",
                            TextColor = Color.White,
                            FontSize = fontSize
                        },

                        ///其他顏色///

                        new Label
                        { Text = "Purple",
                            TextColor = Color.Purple,
                            FontSize = fontSize
                        }
                    }
                }
            };
        }
    }

附錄二,撈出 Xamarin 提供顏色的 ContentPage
*OnPlatform 寫法已更改,請參考此篇文章

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:toolkit= "clr-namespace:Xamarin.FormsBook.Toolkit;assembly=Xamarin.FormsBook.Toolkit" 
             x:Class="DiscreteTabbedColors.NamedColorsPage" 
             Title="Toolkit">
    
    <ContentPage.Icon>
        <OnPlatform x:TypeArguments="FileImageSource" 
                    iOS="ic_action_storage.png" />
    </ContentPage.Icon>
    
    <ListView ItemsSource="{x:Static toolkit:NamedColor.All}">
        <ListView.RowHeight>
            <OnPlatform x:TypeArguments="x:Int32" 
                        iOS="80"
                        Android="80"
                        WinPhone="90" />
        </ListView.RowHeight>
        
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <ContentView Padding="5">
                        <StackLayout Orientation="Horizontal">
                            <BoxView x:Name="boxView" 
                                     Color="{Binding Color}" 
                                     WidthRequest="50"
                                     HeightRequest="50" />
                            <StackLayout>
                                
                                <Label Text="{Binding Name}" 
                                       FontSize="Medium"
                                       VerticalOptions="StartAndExpand" />
                                
                                <Label Text="{Binding RgbDisplay, StringFormat='RGB = {0}'}" 
                                       FontSize="Small"
                                       VerticalOptions="CenterAndExpand" />
                            </StackLayout>
                        </StackLayout>
                    </ContentView>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

附錄三,用 Slider 控制顏色的 ContentPage
*OnPlatform 寫法已更改,請參考此篇文章

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:toolkit= "clr-namespace:Xamarin.FormsBook.Toolkit;assembly=Xamarin.FormsBook.Toolkit" 
             x:Class="DiscreteTabbedColors.ColorTestPage" 
             Title="Test">
    
    <ContentPage.Icon>
        <OnPlatform x:TypeArguments="FileImageSource" 
                    iOS="ic_action_gamepad.png" />
    </ContentPage.Icon>
    
    <StackLayout Padding="20, 40">
        <StackLayout.BindingContext>
            <toolkit:ColorViewModel Color="Gray" />
        </StackLayout.BindingContext>
        
        <Label Text="{Binding Red, StringFormat='Red = {0:F2}'}" 
               HorizontalOptions="Center" />
        
        <Slider Value="{Binding Red}" />
        
        <Label Text="{Binding Green, StringFormat='Green = {0:F2}'}" 
               HorizontalOptions="Center" />
        
        <Slider Value="{Binding Green}" />
        
        <Label Text="{Binding Blue, StringFormat='Blue = {0:F2}'}"
               HorizontalOptions="Center" />
        
        <Slider Value="{Binding Blue}" />
        
        <BoxView Color="{Binding Color}" 
                 VerticalOptions="FillAndExpand" />
        
    </StackLayout>
</ContentPage>


2 則留言:

  1. 您好,請問要如何設定TabbedPage在指定頁面不做顯示?
    目前設定的TabbedPage的ContentPage頁面有ToolbarItems功能,點擊會顯示TabbedPage選單,可以讓他不顯示嗎

    回覆刪除
    回覆
    1. 有點不太清楚你的問題,方便的話用 FB 跟我聯繫,並截圖讓我了解下,我才有辦法回答

      刪除

注意:只有此網誌的成員可以留言。