第二十五章:页面变化(五)

简介: TabbedPage TabbedPage派生自抽象类MultiPage 。它维护一个Page类型的子集合,其中只有一个一次完全可见。 TabbedPage通过页面顶部或底部的一系列选项卡标识每个子项。

TabbedPage

TabbedPage派生自抽象类MultiPage 。它维护一个Page类型的子集合,其中只有一个一次完全可见。 TabbedPage通过页面顶部或底部的一系列选项卡标识每个子项。使用TabbedPage的iOS应用程序必须包含每个选项卡的图标;否则,Apple将不接受App Store的程序。此图标通过每个页面的Icon属性设置。
MultiPage 定义TabbedPage的所有重要属性和事件,其中最重要的是:

  • IList类型的子属性。

通常,您使用页面对象填充此Children集合。
但是,您可以通过观察MultiPage 与ListView的基类ItemsView 非常相似来以稍微不同的方式使用TabbedPage,因为它定义了:

  • IEnnumerable类型的ItemsSource属性,和
  • DataTemplate类型的ItemTemplate属性。

如果提供具有适合数据绑定的公共属性的IEnumerable对象集合,以及具有页面类型作为根元素的模板,则会动态生成子项。该
每个生成的页面的BindingContext设置为等于ItemsSource中的特定对象。
MultiPage 定义了两个属性,可以帮助您的应用程序跟踪用户当前正在查看的Children集合中的哪个页面:

  • T类型的CurrentPage(TabbedPage的页面)。
  • 类型为object的SelectedItem,引用ItemsSource集合中的对象。两个属性都是gettable和settable。

MultiPage 还定义了两个事件:

  • TartsSource集合更改时触发PagesChanged
  • 查看的页面更改时会触发CurrentPageChanged。

最常见的是,您将直接将ContentPage衍生物添加到Children集合中。 如果要使用TabbedPage基于数据集合显示类似页面的集合,您可以选择将ItemsSource属性设置为该集合并使用ItemTemplate定义页面,但在iOS上应避免使用此方法。
离散标签页
TabbedPage的最常见用途是在应用程序中的不同功能之间导航,这通常意味着每个选项卡呈现不同类型的页面。 这些页面通常以某种方式相关 - 也许是应用程序设置的多个页面 - 即使它们看起来不一样。
DiscreteTabbedColors程序有三个选项卡:第一个显示内置Xamarin.Forms颜色的列表,第二个显示Xamarin.FormsBook.Toolkit(前面章节中介绍)中NamedColor类的颜色列表,第三个选项卡 包含颜色测试仪(您可以使用它选择任意RGB值进行预览)。
DiscreteTabbedColors程序以三个ContentPage衍生物开头。 第一个是codeonly,由一个简单的标准Xamarin.Forms颜色列表组成。

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
                    }
                }
            }
        };
    }
}

请注意,Title属性已设置。 这对于所有平台上的选项卡文本都很重要。 该代码还为iOS设置了Icon属性。 特定图标是第13章“位图”中描述的Android图标集的一部分,并且是32像素的正方形。
NamedColorsPage由所有NamedColor对象的ListView组成。 再次注意iOS的Title属性和Icon属性:

<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 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>

这是DiscreteTabbedColorsPage。 注意TabbedPage的根元素。 此XAML文件只是将这三种页面类型的实例添加到TabbedPage的Children集合中:

<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:local="clr-namespace:DiscreteTabbedColors"
            x:Class="DiscreteTabbedColors.DiscreteTabbedColorsPage">
    <local:BuiltInColorsPage />
    <local:NamedColorsPage />
    <local:ColorTestPage />
</TabbedPage>

以下是三个平台上的三个选项卡:
2019_05_09_090941
在iOS上,选项卡位于底部,标有文本和图标,突出显示所选选项卡。 Android和Windows 10 Mobile都会在屏幕顶部显示选项卡,但会以不同方式突出显示所选选项卡。
StudentNotes程序有一个主页,列出ListView中的所有学生,但从该列表中选择一个学生会导致程序导航到TabbedPage。该页面有三个选项卡:第一个显示关于学生的文本信息,第二个显示学生的照片,第三个显示编辑器,允许教师或其他学校管理员输入关于学生的一些注释。 (此功能使用SchoolOfFineArt库中Student类的Notes属性。)
StudentNotes程序中的App类将Application定义的Properties字典传递给SchoolViewModel构造函数,并在程序进入休眠状态时将Properties字典传递给ViewModel的SaveNotes方法,可能是为了准备终止:

public class App : Application
{
    public App()
    {
        ViewModel = new SchoolViewModel(Properties);
        MainPage = new NavigationPage(new StudentNotesHomePage());
    }
    public SchoolViewModel ViewModel
    {
        private set; get;
    }
    protected override void OnStart()
    {
        // Handle when your app starts
    }
    protected override void OnSleep()
    {
        ViewModel.SaveNotes(Properties);
    }
    protected override void OnResume()
    {
        // Handle when your app resumes
    }
}

现在主页应该看起来很熟悉。 它只显示ListView中的所有学生:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:StudentNotes;assembly=StudentNotes"
             x:Class="StudentNotes.StudentNotesHomePage"
             Title="Students"
             BindingContext="{Binding Source={x:Static Application.Current},
                                      Path=ViewModel}">
    <StackLayout BindingContext="{Binding StudentBody}">
        <Label Text="{Binding School}"
               FontSize="Large"
               FontAttributes="Bold"
               HorizontalTextAlignment="Center" />
        <ListView x:Name="listView"
                  ItemsSource="{Binding Students}"
                  ItemSelected="OnListViewItemSelected">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ImageCell ImageSource="{Binding PhotoFilename}"
                               Text="{Binding FullName}"
                               Detail="{Binding GradePointAverage,
                                                StringFormat='G.P.A. = {0:F2}'}" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

代码隐藏文件包含ListView的ItemSelected处理程序,用于导航到StudentNotesDataPage,将页面的BindingContext设置为选定的Student对象:

public partial class StudentNotesHomePage : ContentPage
{
    public StudentNotesHomePage()
    {
        InitializeComponent();
    }
    async void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs args)
    {
        if (args.SelectedItem != null)
        {
            listView.SelectedItem = null;
            await Navigation.PushAsync(new StudentNotesDataPage
            {
                BindingContext = args.SelectedItem
            });
        }
    }
}

StudentNotesDataPage派生自TabbedPage。 在TabbedPage的开始和结束标记内,三个ContentPage定义被添加到TabbedPage的Children属性中。 每个都将其Title属性设置为要在选项卡中使用的文本,并为iOS包含Icon定义:

<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            x:Class="StudentNotes.StudentNotesDataPage"
            Title="Student Data">
    <ContentPage Title="Info">
        <ContentPage.Icon>
            <OnPlatform x:TypeArguments="FileImageSource"
                        iOS="ic_action_about.png" />
        </ContentPage.Icon>

        <StackLayout>
            <Label Text="{Binding FullName}"
                   FontSize="Large"
                   HorizontalOptions="Center" />
            <StackLayout Spacing="12"
                         VerticalOptions="CenterAndExpand"
                         HorizontalOptions="Center">
                <StackLayout.Resources>
                    <ResourceDictionary> 
                        <Style TargetType="Label">
                            <Setter Property="FontSize" Value="Large" />
                        </Style>
                    </ResourceDictionary>
                </StackLayout.Resources>

                <Label Text="{Binding LastName, 
                                      StringFormat='Last name: {0}'}" />

                <Label Text="{Binding FirstName, 
                                      StringFormat='First name: {0}'}" />

                <Label Text="{Binding MiddleName, 
                                      StringFormat='Middle name: {0}'}" />

                <Label Text="{Binding Sex, 
                                      StringFormat='Sex: {0}'}" />

                <Label Text="{Binding GradePointAverage, 
                                      StringFormat='G.P.A. = {0:F2}'}" />
            </StackLayout>
        </StackLayout>
    </ContentPage>
    <ContentPage Title="Photo">
        <ContentPage.Icon>
            <OnPlatform x:TypeArguments="FileImageSource"
                        iOS="ic_action_person.png" />
        </ContentPage.Icon>

        <StackLayout>
            <Label Text="{Binding FullName}"
                   FontSize="Large"
                   HorizontalOptions="Center" />
            <Image Source="{Binding PhotoFilename}"
                   VerticalOptions="FillAndExpand" />
        </StackLayout>
    </ContentPage>
    <ContentPage Title="Notes">
        <ContentPage.Icon>
            <OnPlatform x:TypeArguments="FileImageSource"
                        iOS="ic_action_edit.png" />
        </ContentPage.Icon>

        <StackLayout>
            <Label Text="{Binding FullName}"
                   FontSize="Large"
                   HorizontalOptions="Center" />
            <Editor Text="{Binding Notes}"
                    Keyboard="Text"
                    VerticalOptions="FillAndExpand" />
        </StackLayout>
    </ContentPage>
</TabbedPage>

这可能不足以分散三页,但您可以轻松想象这种方法理想的情况。
以下是三个平台在三个平台上的外观:
2019_05_09_092319
您可以按正常方式导航回学生列表:点击iOS和Android屏幕顶部的左箭头,或者按Android和Windows 10 Mobile屏幕底部的后退箭头。

目录
相关文章
|
6月前
|
前端开发
动态水滴页面
动态水滴页面
40 0
|
2月前
|
前端开发
【前端web入门第五天】03 清除默认样式与外边距问题【附综合案例产品卡片与新闻列表】
本文档详细介绍了CSS中清除默认样式的方法,包括清除内外边距、列表项目符号等;探讨了外边距的合并与塌陷问题及其解决策略;讲解了行内元素垂直边距的处理技巧;并介绍了圆角与盒子阴影效果的实现方法。最后通过产品卡片和新闻列表两个综合案例,展示了所学知识的实际应用。
59 11
|
6月前
|
JSON 定位技术 API
HTML新特性【规划公交路线、规划步行路线、定位、自定义视角动画、账号和获取密钥、初始化、变更地图类型、添加控件、改变控件位置】(五)-全面详解(学习总结---从入门到深化)(下)
HTML新特性【规划公交路线、规划步行路线、定位、自定义视角动画、账号和获取密钥、初始化、变更地图类型、添加控件、改变控件位置】(五)-全面详解(学习总结---从入门到深化)
74 0
|
6月前
|
移动开发 JavaScript 前端开发
HTML新特性【规划公交路线、规划步行路线、定位、自定义视角动画、账号和获取密钥、初始化、变更地图类型、添加控件、改变控件位置】(五)-全面详解(学习总结---从入门到深化)(上)
HTML新特性【规划公交路线、规划步行路线、定位、自定义视角动画、账号和获取密钥、初始化、变更地图类型、添加控件、改变控件位置】(五)-全面详解(学习总结---从入门到深化)
104 0
|
索引
【 uniapp - 黑马优购 | 分类界面 】创建cate分支、数据获取、动态渲染
【 uniapp - 黑马优购 | 分类界面 】创建cate分支、数据获取、动态渲染
160 0
|
存储 小程序 算法
【易售小程序项目】小程序首页完善(滑到底部数据翻页、回到顶端、基于回溯算法的两列数据高宽比平衡)【后端基于若依管理系统开发】
【易售小程序项目】小程序首页完善(滑到底部数据翻页、回到顶端、基于回溯算法的两列数据高宽比平衡)【后端基于若依管理系统开发】
98 0
|
数据采集 监控 数据可视化
做出酷炫的动态统计图表,不一定要写代码
首先这个名字很长的,就是上面 GDP 图表的作者 Jannchie见齐 基于 D3.js 开发的 将历史数据排名转化为动态柱状图图表 的项目,并在 github 上开源了。
|
传感器 网络协议 物联网
5_1_1_首页信息展示屏_整体介绍_技术点及获取电池电量|学习笔记
快速学习5_1_1_首页信息展示屏_整体介绍_技术点及获取电池电量。
315 0
5_1_1_首页信息展示屏_整体介绍_技术点及获取电池电量|学习笔记
|
前端开发
前端工作总结128-一级控制二级菜单的变化
前端工作总结128-一级控制二级菜单的变化
103 0
前端工作总结128-一级控制二级菜单的变化
好客租房140-长列表性能优化(可视区域渲染)
好客租房140-长列表性能优化(可视区域渲染)
98 0
好客租房140-长列表性能优化(可视区域渲染)