XAML in Xamarin.Forms 基礎篇 電子書

XAML in Xamarin.Forms 基礎篇 電子書
XAML in Xamarin.Forms 基礎篇 電子書

Xamarin.Forms 快速入門 電子書

Xamarin.Forms 快速入門 電子書
Xamarin.Forms 快速入門 電子書

2016/07/13

Xamarin.Forms 平台特色

平台特色

在進行 Xamarin.Forms 跨平台應用程式開發的時候,由於,開發者會將大部分的商業邏輯與視覺介面都在核心PCL內進行開發,不過,有些時候在共用的商業邏輯程式碼內或者在共用視覺介面 XAML 定義宣告中,想是根據不同的平台與系統做出不同的反映;這樣的需求,就是這個章節存在的目的。
在這個章節內,開發者可以在核心PCL專案內,
  • 得知使用者當時的裝置是 手機或平板或桌機 (使用 Device.Idiom)
  • 依據使用者當時裝置的作業系統是 iOS/Android/WinPhone/Windows (使用 Device.OS)
  • 在撰寫 XAML 內容時候,需要能夠針對不同的平台,提供不同的視覺效果 (使用 Device.OnPlatform)`
  • 需要能夠使用類似 C# Timer 定時器方法功能,Device.StartTimer)
  • 最後,類似 WPF 開發方式,對於背景執行非同步執行續,有部分程式碼有更新UI內容,這個時候就可以使用 Device.BeginInvokeOnMainThread

建立標籤式的樣板式頁面方案

  1. 首先,開啟您的 Visual Studio 2015
  2. 接著透過 Visual Studio 2015 功能表,選擇這些項目 檔案 > 新增 > 專案 準備新增一個專案。
  3. 接著,Visual Studio 2015 會顯示 新增專案 對話窗,請在這個對話窗上,進行選擇 Visual C# >Cross-Platform > Blank Xaml App (Xamarin.Forms Portable)
  4. 接著,在最下方的 名稱 文字輸入盒處,輸入 XFDevice 這個名稱,最後使用滑鼠右擊右下方的 確定按鈕。
  5. 當專案建立到一半,若您的開發環境還沒有建置與設定完成 Mac 電腦與 Xamarin Studio for Mac 系統,此時會看到 Xamarin Mac Agent Instructions 對話窗出現,這個對話窗是要提醒您進行與 Mac 電腦連線設定,這是因為,您無法在 Windows 作業系統進行 iOS 相關應用程式的建立與設計工作,而是需要透過 Mac 電腦安裝的 XCode 來協助您完成這些 iOS 應用程式的建立工作。不過,這不影響您繼續開發 Xamarin.Forms 的應用程式,只不過此時,您無法編譯與執行 iOS 的應用程式。
  6. 接著會看到 新的通用Windows專案 對話視窗,此時,您只需要按下 確定 按鈕即可,此時,專案精靈會繼續完成相關平台的專案建立工作。
  7. 最後,整個新的 Xamarin.Forms 專案就建立完成了。

MainPage

  • 首先,打開核心PCL 的 MainPage.xaml 檔案,將底下的 XAML 宣告定義複製到這個檔案內。
  • 在應用程式的首頁頁面, 首先使用了 ContentPage.Padding 來定義整個頁面的 Padding 範圍,會要這樣做的原因是,若 Xamarin.Forms 的 ContentPage 在 iOS 平台下執行的話,他會與最上方的狀態列互相重疊,如下圖所示,因此,需要特別針對 iOS 平台進行調整,避免發生這樣的情況。
    解決方案就是定義 ContentPage.Padding,在其裡面使用 OnPlatform x:TypeArguments="Thickness"分別指定個平台所需要的 Thickness 的值。
    iOS_XFDevice1
  • 這個頁面的控制項,使用了 Grid 版面配置來進行所有控制項的定位。
  • 在這個 XAML 範例內,關於 <OnPlatform ...> ... </<OnPlatform> 的使用方式,提供了不同的寫法,不論哪種用法,都具有同樣的效果。
  • 當在 OnPlatform 內,使用了 x:TypeArguments 指定所要客製化的物件值;若所要指定的物件屬於C#的基本型別,此時,您需要使用 XAML 標記延伸功能,使用 x:來指明所要設定的資料型別。

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:XFDevice"
             x:Class="XFDevice.MainPage"
             Title="知道我在哪個平台上嗎?"
             >
  <ContentPage.Padding>
    <OnPlatform x:TypeArguments="Thickness">
      <OnPlatform.iOS>
        0,20,0,0
      </OnPlatform.iOS>
      <OnPlatform.Android>
        0, 0, 0, 0
      </OnPlatform.Android>
      <OnPlatform.WinPhone>
        0, 0, 0, 0
      </OnPlatform.WinPhone>
    </OnPlatform>
  </ContentPage.Padding>

  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="*"/>
      <RowDefinition Height="*"/>
      <RowDefinition Height="*"/>
      <RowDefinition Height="*"/>
      <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="*"/>
      <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <Label
      Grid.Row="0" Grid.Column="0">
      <Label.Text>
        <OnPlatform x:TypeArguments="x:String">
          <OnPlatform.iOS>我正在使用 iOS</OnPlatform.iOS>
          <OnPlatform.Android>我正在使用 Android</OnPlatform.Android>
          <OnPlatform.WinPhone>我正在使用 WinPhone</OnPlatform.WinPhone>
        </OnPlatform>

      </Label.Text>
    </Label>

    <BoxView
      Grid.Row="0" Grid.Column="1"
      HorizontalOptions="Center" VerticalOptions="Center"
      >
      <BoxView.BackgroundColor>
        <OnPlatform x:TypeArguments="Color"
          iOS="Green"
          Android="#738182"
          WinPhone="Accent"
        />
      </BoxView.BackgroundColor>
      <BoxView.WidthRequest>
        <OnPlatform x:TypeArguments="x:Double"
          iOS="130"
          Android="80"
          WinPhone="30" />
      </BoxView.WidthRequest>
      <BoxView.HeightRequest>
        <OnPlatform x:TypeArguments="x:Double"
          iOS="130"
          Android="80"
          WinPhone="30" />
      </BoxView.HeightRequest>
    </BoxView>

    <Label
      x:Name="label處理中"
      Text="處理中"
      HorizontalOptions="Center" VerticalOptions="Center"
      Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
      />

    <Button
      x:Name="button猜猜我是誰"
      Text="猜猜我是誰"
      HorizontalOptions="Center" VerticalOptions="Center"
      Grid.Row="2" Grid.Column="0"
      Clicked="OnGuessClicked" />

    <Button
      x:Name="button定時更新"
      Text="定時更新"
      Grid.Row="2" Grid.Column="1"
      Clicked="OnTimerClicked" />

     <Button
      x:Name="button背景處理中"
      Text="背景處理中"
      Grid.Row="3" Grid.Column="0"
      Clicked="OnBackgroundClicked" />

   <Button
      x:Name="button開啟網頁"
      Text="開啟網頁"
      Grid.Row="3" Grid.Column="1"
      Clicked="OnOpenUriClicked" />

  </Grid>

</ContentPage>
在 MainPage.xaml 的 code-behind 裡面,有定義了相關事件處理用法。
  • 若想要在 C# 中針對不同平台執行不同的程式碼,此時,可以使用 Device.OnPlatform 這個方法,例如,在 OnGuessClicked 按鈕事件方法內,根據不同作業系統與是否為平板或手機,傳回不同的字串,並且顯示在螢幕畫面上。
  • 在核心PCL專案內,若想要使用 C# 的定時器功能 Timer, DispatcherTimer 這類功能,可以使用Device.StartTimer 這個方法來取代;在這個方法內,若想要繼續下一個週期的定時執行,請回傳true,若想要停止週期定時執行,請回傳 false
  • 最後,在 OnBackgroundClicked 這個事件處理方法內,說明了,當使用了非同步的背景執行時候,在背景運行程式碼內,想要更新 UI 內容的時候,您需要透過 Device.BeginInvokeOnMainThread 這個方法,讓您相關更新 UI 內容的程式碼,在 UI 執行續內來執行。

MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace XFDevice
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();

        }

        void OnGuessClicked(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            Device.OnPlatform(
                iOS: ()=>
                {
                    sb.Append("嗯嗯嗯,您是 iOS, ");
                },
                Android: () =>
                {
                    sb.Append("嗯嗯嗯,您是 Android, ");
                },
                WinPhone: () =>
                {
                    sb.Append("嗯嗯嗯,您是 WinPhone, ");
                }
                );
            sb.Append(Device.Idiom.ToString());

            button猜猜我是誰.Text = sb.ToString();
        }

        void OnTimerClicked(object sender, EventArgs e)
        {
            int fooCC = 0;
            int fooMax = 50;
            Device.StartTimer(new TimeSpan(0, 0, 1), () => {

                button定時更新.Text = $"{DateTime.Now}";

                if (++fooCC > fooMax)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            });
        }

        void OnBackgroundClicked(object sender, EventArgs e)
        {
            Task.Factory.StartNew(()=>
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    label處理中.Text = $"處理中 現在時間:{DateTime.Now}";
                });
            });
        }

        void OnOpenUriClicked(object sender, EventArgs e)
        {
            Device.OpenUri(new Uri("http://www.xamarin.com"));
        }
    }
}

實際執行畫面

請再度重新執行,這個時候應用程式可以順利正常運行,螢幕截圖如下:
And_XFDevice

佈署注意事項

iOS 執行結果

請在方案總管內,滑鼠右擊 XFDevice.iOS 專案,選擇 設定為起始專案,接著按下 F5 開始執行。
iOS_XFDevice

佈署注意事項

參考

沒有留言:

張貼留言