Статьи

Введение в Xamarin.Forms для разработчиков Android (часть 5)

Вступление

В программировании на Android объекты Activity используются для отображения информации пользователям, а объекты Intent используются для перемещения между Activity . В Xamarin.Forms мы будем знакомы со страницами, которые похожи на действия, и объектом NavigationPage , который похож на объект Intent .

страницы

В предыдущих статьях мы рассмотрели основы макетов и представлений в Xamarin. Однако мы работали на одной странице. В реальном мире мобильные приложения состоят из нескольких страниц.

Xamarin.Forms предоставляет множество объектов страниц, которые мы можем использовать для настройки пользовательского интерфейса наших приложений, и все они являются производными от класса Page abtract Page . В следующей таблице описаны доступные страницы в Xamarin.Forms:

Тип страницы

Описание

ContentPage

Показать один объект просмотра

TabbedPage

Облегчает навигацию по дочерним страницам с помощью вкладок

CarouselPage

Облегчает использование жеста смахивания среди дочерних страниц

MasterDetailPage

Управляет двумя отдельными панелями, включая элемент управления

NavigationPage

Предоставляет инфраструктуру для навигации по страницам

Мы можем создать объекты страницы тремя способами:

  • Использование XAML
  • Использование кода C #
  • Использование шаблонов элементов предоставляется Visual Studio

Для того , чтобы следовать примерам в этой должности, мы также создаем новый Xamarin.Forms приложение с именем NavigApp .

ContentPage

ContentPage является самым простым объектом страниц и позволяет отображать единый визуальный элемент (или контроль в предыдущем посте ). По умолчанию, когда мы успешно создаем приложение NavigApp , содержимое файла MainPage.xaml может выглядеть следующим образом:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:NavigApp"
             x:Class="NavigApp.MainPage">
       <Label Text="Welcome to Xamarin.Forms!"
           VerticalOptions="Center"
           HorizontalOptions="Center" />
</ContentPage>

В приведенном выше коде XAML объект ContentPage можно создать с помощью элемента <ContentPage> и его атрибутов. Этот объект ContentPage отображает один визуальный элемент, элемент Label . Файл с выделенным кодом ( MainPage.xaml.cs ):

namespace NavigApp
{
       public partial class MainPage : ContentPage
       {
              public  MainPage()
              {
                     InitializeComponent();                    
              }
       }
}

Мы также можем создать ContentPage , используя шаблоны элементов:

  • Щелкните правой кнопкой мыши  проект NavigApp в  окне обозревателя решений и выберите Добавить> Новый элемент

  • Затем выберите параметры и заполните что-нибудь в  диалоговом окне « Добавить новый элемент », как показано на следующем снимке экрана:

Обратите внимание, что мы можем выбрать элемент Content Page , который является шаблоном XAML, или элемент Content Page (C #), который является шаблоном кода C #. ContentPage можно использовать по отдельности или в качестве содержимого других страниц (как вы увидите позже).

MasterDetailPage

MasterDetailPage позволяет нам разделить содержимое на две связанные части: основная часть , которая представляет предметы и деталь часть , которая представляет сведения об объектах на главной части. Следующий код XAML ( файл MainPage.xaml ) покажет, как создать объект MasterDetailPage, и его основная и подробная части представлены объектами ContentPage:

<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:NavigApp"
             x:Class="NavigApp.MainPage" >
    <MasterDetailPage.Master>
        <ContentPage Title="Content Page">
            <Label Text="This is the Master" HorizontalOptions="Center"
                VerticalOptions="Center"/>
        </ContentPage>
    </MasterDetailPage.Master>
    <MasterDetailPage.Detail>
        <ContentPage>
            <Label Text="This is the Details" HorizontalOptions="Center"
                VerticalOptions="Center"/>
         </ContentPage>
    </MasterDetailPage.Detail>
</MasterDetailPage>

Обратите внимание , что мы должны вставить Title свойство для <MasterDetailPage.Master>  «S <ContentPage> элемента. Содержимое файла code-behind ( MainPage.xaml.cs ), соответственно, будет выглядеть так:

namespace NavigApp
{
       public partial class MainPage : MasterDetailPage
    {
              public  MainPage()
              {
                     InitializeComponent();                     
              }
       }
}

Результат:

Вы можете провести слева направо, чтобы включить главный всплывающее окно:

И проведите назад, чтобы скрыть это. Важное примечание из  документов Microsoft :

«Главная страница MasterDetailPage всегда должна быть экземпляром ContentPage, и что страница сведений должна заполняться только экземплярами TabbedPage, NavigationPage и ContentPage. Это поможет обеспечить согласованное взаимодействие с пользователем на всех платформах».

Вы также можете добавить объект MasterDetailPage , добавив шаблон элемента из VisualStudio :

TabbedPage

Объект TabbedPage используется в тех случаях, когда вам нужно классифицировать несколько страниц по темам или видам деятельности. Вы можете сгруппировать несколько объектов ContentPage во вкладки в виде следующего кода XAML (MainPage.xaml):

<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:NavigApp"
             x:Class="NavigApp.MainPage" >
    <TabbedPage.Children>
        <ContentPage Title="First">
            <Label Text="This is the first page" HorizontalOptions="Center" VerticalOptions="Center"/>
        </ContentPage>
        <ContentPage Title="Second">
            <Label Text="This is the second page" HorizontalOptions="Center" VerticalOptions="Center"/>
        </ContentPage>
        <ContentPage Title="Third">
            <Label Text="This is the third page" HorizontalOptions="Center" VerticalOptions="Center"/>
        </ContentPage>
    </TabbedPage.Children>
</TabbedPage>

И выделенный код (MainPage.xaml.cs):

namespace NavigApp
{
       public partial class MainPage : TabbedPage
    {
              public  MainPage()
              {
                     InitializeComponent();                     
        }
       }
}

Результаты выглядят так:

Как видите, мы организовали несколько объектов ContentPage в коллекцию TabbedPage.Children, и мы также должны предоставить заголовок, который является заголовком каждой вкладки, для каждого ContentPage.

Мы также можем добавить объект TabbedPage, добавив шаблон элемента из Visual Studio:

CarouselPage

CarouselPage похож на TabbedPage , но вместо того , чтобы вкладки, можно использовать салфетки жест для переключения между дочерними страницами. Следующий код XAML демонстрирует галерею изображений с использованием CarouselPage:

<?xml version="1.0" encoding="utf-8" ?>
<CarouselPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:NavigApp"
             x:Class="NavigApp.MainPage" >
    <CarouselPage.Children>
        <ContentPage Title="First">
            <Image Source="cat.jpg" HorizontalOptions="Center" VerticalOptions="Center"/>
        </ContentPage>
        <ContentPage Title="Second">
            <Image Source="dog.jpg" HorizontalOptions="Center" VerticalOptions="Center"/>
        </ContentPage>
        <ContentPage Title="Third">
            <Image Source="mouse.jpg" HorizontalOptions="Center" VerticalOptions="Center"/>
        </ContentPage>
    </CarouselPage.Children>
</CarouselPage>

И код позади, соответственно:

namespace NavigApp
{
       public partial class MainPage : CarouselPage
    {
              public  MainPage()
              {
             InitializeComponent();
        }
       }
}

Результат:

Переходя на вторую страницу:

И третья страница:

Обратите внимание, что мы должны импортировать изображения в папку Resource> drawable  в проекте Android:

Навигация между страницами

In theory, to move from one page to another, an application will push a new page onto the navigation stack, where it will become the active page, and to return back to the previous page, the application will pop the current page from the navigation stack. We can pass data from a page to another page during navigation.

In practice, the navigation includes the following operators:

  • Creating a root page, which is the first page is added to a navigation stack by using the NavigationPage object, in the App.xaml.cs file.
  • Navigating to the next page by pushing this page to the navigation stack. We can use methods such as the PushAsync or the PushModalAsync on the Navigation property of the current page.
  • By default, we can use the Back button on the device to naviage back to previous page but we can program by using the PopAsync or the PopModalAsync on the Navigation property to pop the active page from the navigation stack.
  • Passing data when navigating through a page constructor or a BindingContext.

In our NavigApp application, suppose the NagvigApp application has the MainPage.xaml as follows:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:NavigApp"
             x:Class="NavigApp.MainPage"
             Title="Main Page">
    <StackLayout>
    <Label Text="I am Main Page" HorizontalOptions="Center"
VerticalOptions="Center"/>
        <Button Text="Next Page" HorizontalOptions="Center" VerticalOptions="Center"
Clicked="nextPage"/>
    </StackLayout>
</ContentPage>

And the MainPage.xaml.cs:

namespace NavigApp
{
       public partial class MainPage : ContentPage
    {
       public  MainPage()
       {
             InitializeComponent();                            
        }
        private void nextPage(object sender, EventArgs e)
        {
        }
    }
}

The nextPage method is Click event handler of the Next Page button. If you run the NavigApp, the result can look like this:

We can push the MainPage to the navigation stack or the MainPage will become the root page by modifying the constructor App of the App class in the App.xaml.cs file:

namespace NavigApp
{
       public partial class App : Application
       {
              public App ()
              {
                     InitializeComponent();
                     //MainPage = new NavigApp.MainPage();
                     MainPage = new NavigationPage(new MainPage());
              }
...
}

If you run the app now, the result will look like this:

A navigation bar is present at the top of the MainPage page that displays a title. Next, we will add a second page named SecondPage to project:

The SecondPage.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="NavigApp.SecondPage"
             Title="Second Page">
    <ContentPage.Content>
        <StackLayout>
            <Label Text="Welcome to second page!"
                VerticalOptions="CenterAndExpand"
                HorizontalOptions="CenterAndExpand" />
            <Button Text="Previous Page"
                VerticalOptions="CenterAndExpand"
                HorizontalOptions="CenterAndExpand"
                    Clicked="prevPage"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

The SecondPage.xaml.cs:

namespace NavigApp
{
       [XamlCompilation(XamlCompilationOptions.Compile)]
       public partial class SecondPage : ContentPage
       {
              public SecondPage ()
              {
                     InitializeComponent ();
              }
              private void prevPage(object sender, EventArgs e)
              {
              }
       }
}

To move from the MainPage page to the SecondPage page by clicking the NextPage button, we must push the SecondPage page to the navigation stack. In the nextPage method, we write something:

async private void nextPage(object sender, EventArgs e)
     {
         await Navigation.PushAsync(new SecondPage());
     }

Note that we must add the async keyword to declaration of the nextPage method. And now, we can run app again and click the Next Page button, app will navigate to the SecondPage page:

We can navigate back to the MainPage page by clicking the Back button, however, we can do this by making some changes in the prevPage method, which is the Click event handler of the PREVIOUS PAGE button:

async private void prevPage(object sender, EventArgs e)
   {
            await Navigation.PopAsync();
   }

When navigating, we can pass data to the MainPage page through a page constructor parameter, which is shown the following changes:

  • In the App() constructor: adding a parameter to the constructor of NavigationPage
public App ()
{
    InitializeComponent();
MainPage = new NavigationPage(new MainPage("Minh"));
}
  • In the MainPage.xaml: adding the x:Name property and modifying the Text property in the Label
  • <ContentPage ...>
        <StackLayout>
            <Label x:Name="name" Text="I am " HorizontalOptions="Center" 
                   VerticalOptions="Center"/>
            <Button .../>
        </StackLayout>
    </ContentPage>
    • In the MainPage.xaml.cs: adding some code to the MainPage constructor:
    public  MainPage(string name)
           {
                InitializeComponent();
                var lbName = this.FindByName<Label>("name");
                lbName.Text += name;    
            }

    The result:

    We can also pass data to the MainPage page through a BindingContext, which will be discovered in the next article.

    Conclusion

    In this article, I introduced about pages and navigating among pages in Xamarin.Forms. I also introduced how to pass data when navigating by using a page constructor parameter. You can learn more about all of them by checking out the Microsoft docs.