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