將視覺控制項新增至 Xamarin.Forms 行動應用程式

已完成

在此課程模組中,我們將深入了解 Xamarin.Forms 應用程式和瀏覽架構的建置組塊,並開始定義自訂 UI。

Xamarin.Forms 專案中有什麼?

為我們的「空白應用程式」範本建立的 Xamarin.Forms 應用程式會以兩個類別作為開頭:App 和 MainPage。 這些類別的 .cs 檔案實際上是「藏在」[方案總管] 中 App.xamlMainPage.xaml 檔案清單底下。

.xaml 檔案本身是一個無須使用程式碼即可定義應用程式使用者介面 (UI) 的實用方式。 其有點類似於 HTML--一種描述 UI 版面配置的標記語言。 使用 XAML 有一些優點,以程式碼建立 UI 也有一些優點。

應用程式類別

App 類別代表我們的 Xamarin.Forms 應用程式整體,並且會繼承自 Xamarin.Forms.Application。 我們將從上一個單元回想起它是前端專案所具現化並載入的 App 類別。 App 類別的建構函式會接著設定自己的 MainPage 屬性。 這就是將控制使用者所見第一個畫面的屬性。

App 類別也包含:

  • 處理生命週期事件的方法,包括將應用程式傳送到背景時 (也就是當它不再是前景應用程式時)。
  • 回應強制回應堆疊中之變更的事件 (這是一種瀏覽類型,在另一個課程模組中有相關討論)。
  • 一個稱為 Properties 的屬性。 這是一個會自動保存新增至其中之任何資料的 PropertyBag

頁面

頁面是 Xamarin.Forms 中 UI 階層的根。 到目前為止,我們所看到的解決方案包含一個稱為 MainPage 的類別。 MainPage 類別衍生自 ContentPage,是最簡單且最常見的頁面類型。 內容頁面會直接顯示其內容。 Xamarin.Forms 也具有數個其他內建的頁面類型,包括下列類型:

  • FlyoutPage:管理兩個資訊窗格。 一般會顯示清單或功能表的 Flyout 頁面,以及顯示飛出視窗頁面所選取項目的 Detail 頁面。
  • NavigationPage 會將熟悉的導覽列新增至畫面頂端,但更重要的是會管理「瀏覽堆疊」。 此堆疊可讓使用者往回瀏覽至先前的畫面。
  • TabbedPage:用於索引標籤瀏覽的根頁面。

如您所見,其他頁面類型大多用於在多重畫面應用程式中啟用不同的瀏覽模式。 我們會在另一個課程模組中探討這些模式。

如何建置內容頁面

我們現在已知道若要在應用程式中顯示內容,我們將會想要使用內容頁面。 那麼,讓我們開始了解如何建立頁面,來以我們想要的方式配置我們想要的內容。

檢視

Xamarin.Forms 中的檢視就像我們已在其他 UI 架構中使用的控制項。 Xamarin.Forms 文件 (請參閱此課程模組結尾的連結) 會說明所有內建控制項,但這裡可以看到一些最常見的控制項:

有數個 iOS UI 控制項的行動裝置螢幕擷取畫面:標籤、項目、按鈕、日期選擇器、活動指示器、進度列、滑桿、切換開關與步進器。

Xamarin.Forms 中的檢視會使用我們已在其他 .NET 型 UI 架構中看到的事件處理和屬性設定模式。

例如,您可以使用下列程式碼來建立新按鈕並設定其 .Text 屬性,以及建立 .Clicked 事件訂閱者:

var button = new Button() {
    Text = "Click Me"
};
button.Clicked += OnClick
void OnClick (object sender, EventArgs e) { /*do something*/ }

不過,讓我們進一步探究此程式碼。 在 iOS 上,我們會獲得一個預設外觀的 iOS 按鈕。 在 Android 上,我們會獲得一個 Android 按鈕。

顯示如何在執行階段將 Xamarin.Forms 按鈕轉譯為原生控制項 (可以是 Android.Widget.Button 或 iOS UIKit.UIButton) 的圖解。

之所以會以此方式運作,是因為 Xamarin.Forms 並不會直接繪製任何控制項。 取而代之的是,每個控制項在每個平台上都有一個平台轉譯器。 因此,當我們在 Android 上執行時,會叫用 Android 按鈕轉譯器來建立原生按鈕。

我們也可以透過在 Xamarin.Forms 物件上設定屬性來控制我們控制項的外觀。 平台轉譯器會為我們執行所有必要的類型轉換和轉譯。 它也會在每次我們變更 Xamarin.Forms 視覺屬性時,在基礎原生控制項上設定屬性。

Xamarin.Forms 並不會公開控制項的所有原生屬性。 但仍有辦法可取得我們可能想要的所有自訂。 我們將在另一個課程模組中了解這些技術。

版面配置

定義頁面和檢視之後,我們似乎已擁有開始建立 UI 所需的一切項目。 不過,假設我們將兩個控制項新增至頁面:一個輸入欄位和一個按鈕。 在某些 UI 架構中,我們會假設這些控制項的流程方向會由上至下和由左至右,而高度、寬度及分行符號會以控制項屬性來設定。

但在 Xamarin.Forms 中,我們會使用更有彈性的系統,稱為版面配置。 當您選擇某個版面配置時,也就是在選擇配置控制項時將依據的規則。

顯示 Xamarin.Forms 版面配置類型之視覺化表示的圖解:StackLayout、AbsoluteLayout、RelativeLayout、Grid 與 ScrollView。

這些圖解顯示一些內建的版面配置類型。 我們將在未來的課程模組中進一步了解它們全部,但讓我們先來快速了解一下:

  • StackLayout - 依據方向屬性,以由上至下或由左至右的堆疊來配置控制項。
  • AbsoluteLayout - 可讓我們設定控制項的確切座標。
  • RelativeLayout - 可讓我們定義多個控制項之大小與形狀之間的關聯性。 例如,button1 的大小應該是 entry1 的 50%,且應該在其底下 5 點的位置。
  • Grid - 根據我們設定的資料行和資料列位置來配置其控制項。 我們可以定義資料行和資料列大小以及範圍,因此格線版面配置不一定會有「棋盤式外觀」。
  • ScrollView - 就技術上而言,並不將此視為版面配置,因為它只直接保存一個子系,但對畫面版面配置非常重要。 根據預設,所有其他版面配置實際上都會視需要嘗試擠壓其內容,以符合單一畫面大小。 但如果這些其他版面配置被放在 ScrollView 內,畫面便可以捲動,而不需要擠壓內容。

我們也可以將版面配置放在巢狀結構中以享有更多彈性。

針對概念證明,我們唯一需要的版面配置是 StackLayout。 為了使用它,我們會將它具現化,然後確定已設定方向屬性,因為我們需要此屬性來讓子系的流程方向為由上至下:

var layout = new StackLayout{
    Orientation = StackOrientation.Vertical
};

接著,我們可以使用其 Children 屬性來為其新增控制項。

layout.Children.Add(new Label {Text="Enter Name"});
layout.Children.Add(new Entry());
layout.Children.Add(new Button{ Text= "Ok"});

我們設定的 Orientation 屬性會控制堆疊的流程方向。 顯示垂直由上而下堆疊子檢水平從左至右 StackLayout 堆疊子檢視間之差異的圖解。

根據預設,當我們使用 .Vertical 方向時,每個控制項都會填滿父系的寬度。

既然我們已擁有已新增控制項的 StackLayout,現在則需要為我們 .ContentContentPage 屬性新增版面配置。 在內容頁面中,如果您已建立上述版面配置,您會新增此指派以顯示內容頁面的版面配置。

this.Content = layout;

這會促使 mainPage 使用 StackLayout 類別的版面配置規則與我們在此類別上設定的屬性,來顯示 StackLayout 的內容。

配置空白空間

我們概念證明應用程式的相當良好版面配置也需要給予控制項一些活動空間。 視我們想要達到的目的而定,有一些不同的屬性可供我們用來進行此操作。

每個控制項都有版面配置所遵守的 .Margin 屬性。 您可以將邊界想像成將其他控制項推開的控制項。

所有版面配置都有防止其任何子系靠近版面配置框線的 .Padding 屬性。 此情況的其中一個思考方式是想像所有控制項都在一個方塊中,而該方塊具有填補的牆。

與我們第一個 Xamarin.Forms 應用程式相關的最後一個空白空間設定是 StackLayout.Spacing 屬性。 這是 StackLayout 所有子系之間的空間。 這會與控制項本身的邊界相加,因此在邊界和間距兩者都適用的地方,實際空白空間會是邊界再加上間距。

檢定您的知識

1.

下列當中哪些不是Xamarin.Forms 中的版面配置類型?

2.

哪一個是用來在 Xamarin.Forms 中建立畫面的類別?

3.

Xamarin.Forms 是否會在執行階段於每個平台上建立原生控制項?

4.

哪個 Xamarin.Forms 頁面類型可用於堆疊型瀏覽,並提供您上一頁按鈕來瀏覽至堆疊中的上一頁?