XamarinForms 系列課程

特別說明

2018/01/07

Xamarin.Forms / .NET Standard 體驗之旅5 : 彈出頁面Prism.Plugin.Popups

最近這段時間都在忙於公司相關事務上,因為最近幾天感冒,嚴重咳嗽,頭昏昏的,趁著今天有一點點好轉,繼續進行Xamarin.Forms / .NET Standard 體驗之旅5 的文章中,在這裡需要測試、使用我之前就很想使用的一個套件:Rg.Plugins.Popup。
Rg.Plugins.Popup 套件可以讓您設計的頁面,以彈出方式來顯示在手機螢幕,若此時,我們停用了手機上的實體回上頁按鈕功能,此時,使用者就必須完成該彈出視窗所指定要輸入的功能,或者在彈出視窗中點選取消按鈕,這樣,才會回到最初的螢幕頁面。
在下圖為我們的起始頁面,這個頁面上只有一個按鈕,這個時候,就會彈出我們設計需要使用者輸入帳號與密碼的彈出視窗。
Rg.Plugins.popup
下圖是彈出視窗的顯示結果,四周的綠色遮罩使用螢幕的方式來顯示,甚至連狀態列也會在遮罩顯示範圍,因此,您將看不到導航頁面的回上頁軟體按鈕,想要取消這個彈出視窗,需要點選紅色X圓圈,這樣,才會取消這個彈出視窗。
Rg.Plugins.popup
不過,想要做到這樣的功能,我們需要使用相當多的Code Behind程式碼來完成這樣的需求;在幾天之前,我看到了Prism.Plugin.Popups這個套件,它提供了擴充方法,可以讓我們使用Prism的導航物件服務,一樣可以做到彈出視窗的效果。

測試範例專案原始碼

這篇文章中的測試範例專案原始碼,您可以從這裡取得 https://github.com/vulcanlee/xamarin-forms-develop-notes-example/tree/master/XFPopup

開始建立專案

請點選功能表[檔案] > [新增] > [專案],此時,您會看到底下的[新增專案] 對話視窗。
我們點選Prism Template Pack 提供的Xamarin.Forms 專用的專案樣板,請點選[已安裝] > [Visual C#] > [Prism] > [Prism Blank App (Xamarin.Forms)]。
接著在名稱欄位輸入該專案名稱後,點選[確定] 按鈕,以建立此練習專案。
然後,在[PRISM PROJEC WIZAD] 對話窗中,選擇您要跨平台的作業系統,容器(Container) 這裡,我個人喜歡與習慣使用 Unity,您可以選擇您自己要用的容器,最後,點選[ CREATE PROJECT] 按鈕。
.NET Standard Xamarin.Forms Project

安裝Prism.Plugin.Popups.Unity NuGet 套件

在這裡,請使用滑鼠右建,點選剛剛建立好的共用類別庫(也就是.NET Standard 標準類別庫)節點,選擇[管理方案的NuGet 套件] 項目。
在[瀏覽]標籤頁次上,輸入Prism.Plugin.Popups.Unity這個關鍵字,搜尋出這個套件。請選擇Prism.Plugin.Popups.Unity這個套件,要來安裝到.NET Standard專案內。

首頁頁面按鈕事件

首頁頁面的XAML相當的簡單,因為,該頁面上只有一個按鈕,讓我們看看,如何顯示這個彈出視窗;當使用按下按鈕之後,我們需要呼叫_navigationService.PushPopupPageAsync這個方法,該方法是因為安裝了Prism.Plugin.Popups.Unity套件,所提供的擴充方法。
using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;

namespace XFPopup.ViewModels
{

    public class MainPageViewModel : INotifyPropertyChanged, INavigationAware
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public DelegateCommand OpenCommand { get; set; }

        private readonly INavigationService _navigationService;

        public MainPageViewModel(INavigationService navigationService)
        {
            _navigationService = navigationService;

            OpenCommand = new DelegateCommand(async () =>
            {
                var fooPara = new NavigationParameters();
                fooPara.Add("From", "從主頁面來彈出");
                await _navigationService.PushPopupPageAsync("NewPage1Page", fooPara);
            });
        }

        public void OnNavigatedFrom(NavigationParameters parameters)
        {

        }

        public void OnNavigatingTo(NavigationParameters parameters)
        {

        }

        public void OnNavigatedTo(NavigationParameters parameters)
        {

        }

    }

}

新增彈出視窗頁面

接下來,我們需要新建立一個彈出視窗頁面,我們需要使用PopupPage類別來建立起可彈出的視窗頁面,而其他的設計方法,就如同我們在設計ContentPage相同。
<?xml version="1.0" encoding="utf-8" ?>
<pages:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
             xmlns:animations="clr-namespace:Rg.Plugins.Popup.Animations;assembly=Rg.Plugins.Popup"
             x:Class="XFPopup.Views.NewPage1Page"
             HasSystemPadding="False"
             >

    <pages:PopupPage.Resources>
        <ResourceDictionary>
            <Style x:Key="EntryStyle" TargetType="Entry">
                <Setter Property="PlaceholderColor" Value="#9cdaf1"/>
                <Setter Property="TextColor" Value="#7dbbe6"/>
            </Style>
        </ResourceDictionary>
    </pages:PopupPage.Resources>
    <pages:PopupPage.Animation>
        <animations:ScaleAnimation
      PositionIn="Bottom"
      PositionOut="Center"
      ScaleIn="1"
      ScaleOut="0.7"
      DurationIn="700"
      EasingIn="BounceOut"/>
    </pages:PopupPage.Animation>

    <Grid
        >
        <BoxView Color="YellowGreen" Opacity="0.6">
        </BoxView>
        <ScrollView
            HorizontalOptions="Center"
            VerticalOptions="Center">
            <Grid
                HorizontalOptions="Center">
                <StackLayout
                    HorizontalOptions="Center" VerticalOptions="Center"
                    BackgroundColor="White">
                    <StackLayout
                        IsClippedToBounds="True"
                        Spacing="3">
                        <Image
                            HorizontalOptions="Center"
                            x:Name="OctocatImage"
              Margin="10"
              HeightRequest="150"
              WidthRequest="150">
                            <Image.Source>
                                <OnPlatform
                  x:TypeArguments="ImageSource"
                  Android="github_octocat.png"
                  iOS="github_octocat.png"
                  WinPhone="Assets/github_octocat.png"/>
                            </Image.Source>
                        </Image>
                        <Label
                            HorizontalOptions="Center"
                            FontSize="20"
                            Text="{Binding From}"/>
                        <Entry
              HorizontalOptions="Center"
              x:Name="UsernameEntry"
              Style="{StaticResource EntryStyle}"
              Placeholder="Username" />
                        <Entry
              HorizontalOptions="Center"
              x:Name="PasswordEntry"
              Style="{StaticResource EntryStyle}"
              Placeholder="Password"
              IsPassword="True"/>
                        <Button
            Margin="10, 5"
            BackgroundColor="#7dbbe6"
            HorizontalOptions="Fill"
            Clicked="OnLogin"
            x:Name="LoginButton"
            Text="Login">
                        </Button>
                    </StackLayout>
                </StackLayout>
                <ContentView
                    HorizontalOptions="End" VerticalOptions="Start"
                >
                    <ContentView.GestureRecognizers>
                        <TapGestureRecognizer Tapped="OnCloseButtonTapped"/>
                    </ContentView.GestureRecognizers>
                    <Image
          x:Name="CloseImage"
          HeightRequest="30"
          WidthRequest="30">
                        <Image.Source>
                            <OnPlatform
              x:TypeArguments="ImageSource"
              Android="close_circle_button.png"
              iOS="close_circle_button.png"
              WinPhone="Assets/close_circle_button.png"/>
                        </Image.Source>
                    </Image>
                </ContentView>
            </Grid>
        </ScrollView>
    </Grid>
</pages:PopupPage>
接著我們打開彈出視窗頁面ViewModel檔案,修正ViewModel 的商業邏輯程式碼。
在這裡,我們展示的是使用Code Behind的方式,來關閉這個彈出視窗:await Navigation.PopAllPopupAsync();,當然,您也可以在ViewModel上來進行這樣效果的操作。
using Rg.Plugins.Popup.Pages;
using System;
using Xamarin.Forms;
using Rg.Plugins.Popup.Extensions;

namespace XFPopup.Views
{
    public partial class NewPage1Page : PopupPage
    {
        public NewPage1Page()
        {
            InitializeComponent();
        }

        protected override bool OnBackButtonPressed()
        {
            return true;
        }
        private async void OnLogin(object sender, EventArgs e)
        {
            //var loadingPage = new LoadingPopupPage();
            //await Navigation.PushPopupAsync(loadingPage);
            //await Task.Delay(2000);
            //await Navigation.RemovePopupPageAsync(loadingPage);
            //await Navigation.PushPopupAsync(new LoginSuccessPopupPage());
        }

        private void OnCloseButtonTapped(object sender, EventArgs e)
        {
            CloseAllPopup();
        }

        protected override bool OnBackgroundClicked()
        {
            CloseAllPopup();

            return false;
        }

        private async void CloseAllPopup()
        {
            await Navigation.PopAllPopupAsync();
        }

    }
}

沒有留言:

張貼留言