您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關如何借助Xamarin.Forms跨移動平臺共享UI代碼,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
借助 Xamarin,您可以使用 C# 構建美觀的本機移動應用和在平臺之間共享您的大部分代碼。傳統上,您必須對每個目標平臺設計單獨的 UI。但是,借助 Xamarin.Forms,您可以構建一個在所有平臺中本機呈現的 UI。
Xamarin.Forms 是跨平臺 UI 抽象層。可以使用它在平臺間共享 UI 和后端代碼,而同時仍提供完全本機 UI 體驗。因為它們是本機的,所以您的控件和小組件將具有每個目標平臺的外觀。
Xamarin.Forms 與 Model-View-ViewModel (MVVM) 設計模式完全兼容,因此可以在視圖模型類中將頁面元素綁定到屬性和命令。
如果您愿意以聲明方式設計您的頁面,則可以使用標記語言 XAML,XAML 具有資源字典、動態資源、數據綁定、命令、觸發器和行為等功能。
Xamarin.Forms 有一個小巧、易于使用的 API。如果您需要更深入地訪問平臺的本機 UI,可以創建自定義視圖和特定于平臺的呈現器。這盡管聽起來很復雜,但它實際上只是一種可訪問本機 UI 的方法,并且 Xamarin 網站有充足示例來幫助您完成該任務。
您可以使用 Xamarin.Forms 附帶的任何現成頁面、布局和視圖開始操作。在您的應用逐漸完善并且您發現新用例和設計機會時,您可能馬上就需依賴 Xamarin.Forms 支持 XAML、MVVM、特定于自定義平臺的呈現器和各種其他功能(如動畫和數據模板)。
我將使用特定示例概述 Xamarin 功能,演示如何在不同的目標平臺之間共享大部分 UI 代碼,以及如何在必要時合并特定于平臺的代碼。
首先,打開 Visual Studio 或 Xamarin Studio 中的 NuGet 包管理器,并檢查 Xamarin.Forms 是否為新版本。因為僅僅在任一 IDE 中打開 Xamarin.Forms 解決方案,不會告知您新版本,所以檢查更新的 NuGet 包是否為確保獲得最新增強功能的唯一方法。
創建 Xamarin.Forms 解決方案確保您已獲得最新版本 Xamarin.Forms 后,創建一個空白應用 (Xamarin.Forms Portable) 解決方案。
您的解決方案具有三個特定于平臺的項目和一個可移植類庫 (PCL)。在 PCL 中創建您的頁面。首先創建一個基本的登錄頁面。
使用 C# 創建頁面向 PCL 項目中添加一個類。然后添加控件(在 Xamarin 中稱為“視圖”),如圖 1 中所示。
圖 1 添加視圖(控件)
public class LogInPage : ContentPage { public LogInPage() { Entry userEntry = new Entry { Placeholder = "Username" }; Entry passEntry = new Entry { Placeholder = "Password", IsPassword = true }; Button submit = new Button { }; Content = new StackLayout { Padding = 20, VerticalOptions = LayoutOptions.Center, Children = { userEntry, passEntry, submit } }; } }
若要在應用啟動時顯示頁面,打開 MyApp 類并將其中一個實例分配給 MainPage 屬性:
public class MyApp : Application { public MyApp() { MainPage = new LogInPage(); } }
這是討論應用程序類的好時機。從 v1.3.0 開始,所有 Xamarin.Forms 應用將都包含此類。它是 Xamarin.Forms 應用的入口點,除此之外,它還提供了生命周期事件以及所有可序列化數據的永久數據存儲區(屬性字典)。如果需要從應用任意位置訪問此類的實例,您可以使用靜態 Application.Current 屬性。
在前面的示例中,我已刪除應用程序類內部的默認代碼,并用一行代碼代替,從而使 LogInPage 顯示您何時運行應用。它顯示應用何時運行,因為此代碼將頁面 (LogInPage) 分配給了應用程序類的 MainPage 屬性。您必須在應用程序類的構造函數中對其進行設置。
您還可以重寫此類中的三個方法:
OnStart 方法,第一次啟動應用時調用。
OnSleep 方法,當應用要進入后臺狀態時調用。
OnResume 方法,當從后臺狀態返回應用時調用。
一般情況下,頁面不是非常有趣,直到您將他們與某種形式的數據或行為連接,因此我將介紹如何執行該操作。
將頁面綁定到數據如果您使用 MVVM 設計模式,則可以創建一個(如圖 2 中所示)實現 INotifyPropertyChanged 接口的類。
圖 2 實現 INotifyPropertyChanged 接口
public class LoginViewModel : INotifyPropertyChanged { private string usrnmTxt; private string passWrd; public string UsernameText { get { return usrnmTxt; } set { if (usrnmTxt == value) return; usrnmTxt = value; OnPropertyChanged("UsernameText"); } } public string PassWordText { get { return passWrd; } set { if (passWrd == value) return; passWrd = value; OnPropertyChanged("PassWrd"); } } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }
您可以將登錄頁面的視圖綁定到該類的屬性(如圖 3 中所示)。
圖 3 將視圖綁定到類屬性
public LogInPage() { Entry userEntry = new Entry { Placeholder = "Username" }; userEntry.SetBinding(Entry.TextProperty, "UsernameText"); Entry passEntry = new Entry { Placeholder = "Password", IsPassword = true }; passEntry.SetBinding(Entry.TextProperty, "PasswordText"); Button submit = new Button { Text = "Submit" }; Content = new StackLayout { Padding = 20, VerticalOptions = LayoutOptions.Center, Children = { userEntry, passEntry, submit } }; BindingContext = new LoginViewModel(); }
若要閱讀有關如何綁定到 Xamarin.Forms 應用中數據的詳細信息,請參閱 Xamarin 站點 bit.ly/1uMoIUX 上的“從數據綁定到 MVVM”。
使用 XAML 創建頁面對于較小的應用,使用 C# 創建 UI 是完全合理的方法。但是,隨著應用大小的增長,您可能會發現自己鍵入了大量的重復代碼。您可以通過使用 XAML 避免該問題,,而不是通過 C# 代碼。
將窗體 XAML 頁面項添加到您的 PCL 項目。然后將標記添加到頁面,如圖 4 中所示。
圖 4 將標記添加到窗體 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="Jason3.LogInPage" xmlns:local="clr-namespace:XamarinForms;assembly=XamarinForms"> <StackLayout VerticalOptions="Center"> <StackLayout.BindingContext> <local:LoginViewModel /> </StackLayout.BindingContext> <Entry Text="{Binding UsernameText}" Placeholder="Username" /> <Entry Text="{Binding PasswordText}" Placeholder="Password" IsPassword="true" /> <Button Text="Login" Command="{Binding LoginCommand}" /> </StackLayout> </ContentPage>
如果您編寫過 Windows Presentation Foundation (WPF) 應用,那么會對圖 4 中的 XAML 感到很熟悉。但是,這些標記是不同的,因為它們指的是 Xamarin.Forms 類型。此外,根元素引用 Xamarin.Forms.Element 類的子類。Xamarin.Forms 應用中的所有 XAML 文件必須都這樣做。
若要了解有關使用 XAML 在 Xamarin.Forms 應用中創建頁面的詳細信息,請參閱 Xamarin 網站 bit.ly/1xAKvRN 上的“適用于 Xamarin.Forms 的 XAML”。
與其他本機移動平臺相比,Xamarin.Forms 具有相對較少的 API。這樣您可以更輕松地設計頁面,但有時 Xamarin.Forms 不按您想要的方式在一個或多個平臺目標上呈現視圖。
如果遇到此障礙,只需創建自定義視圖,這只是一個可用于 Xamarin.Forms 的任何視圖的子類。
若要使視圖顯示在頁面上,請擴展視圖呈現器。在更高級的情況下,您甚至可以從頭創建自定義呈現器。自定義呈現器代碼是特定于平臺的,因此您不能共享此代碼。但這種方法值這個價格,因為它可以引入本機功能和應用可用性。
創建自定義視圖首先,創建 Xamarin.Forms 中提供的任一視圖的子類。下面是兩個自定義視圖的代碼:
public class MyEntry : Entry {} public class RoundedBoxView : BoxView {}
擴展現有的呈現器圖 5 擴展可以呈現 iOS 平臺的條目視圖的呈現器。您應將此類放在 iOS 平臺項目中。此呈現器設置底層本機文本字段的顏色和樣式。
圖 5 擴展現有的呈現器
[assembly: ExportRenderer (typeof (MyEntry), typeof (MyEntryRenderer))] namespace CustomRenderer.iOS { public class MyEntryRenderer : EntryRenderer { protected override void OnElementChanged (ElementChangedEventArgs<Entry> e) { base.OnElementChanged (e); if (e.OldElement == null) { var nativeTextField = (UITextField)Control; nativeTextField.BackgroundColor = UIColor.Gray; nativeTextField.BorderStyle = UITextBorderStyle.Line; } } } }
您可以在呈現器上執行幾乎任何操作,因為您正在引用本機 API。如果您想要查看包含此代碼段的示例,請參閱 bit.ly/1xTIjmR 上的“Xamarin.Forms 自定義呈現器”。
從頭開始創建呈現器可以創建不擴展任何其他呈現器的全新呈現器。創建呈現器會需要您做更多的工作,但是這有益于執行以下任一操作:
替換視圖的呈現器。
將新的視圖類型添加到您的解決方案。
將本機控件或本機頁面添加到您的解決方案。
例如,如果您想要將本機 UIView 控件添加到 iOS 版本應用的頁面中,則應將自定義呈現器添加到您的 iOS 項目,如圖 6 中所示。
圖 6 將本機 UIView 控件添加到配備自定義呈現器的 iOS 應用
[assembly: ExportRendererAttribute(typeof(RoundedBoxView), typeof(RoundedBoxViewRenderer))] namespace RBVRenderer.iOS { public class RoundedBoxViewRenderer : ViewRenderer<RoundedBoxView,UIView> { protected override void OnElementChanged( ElementChangedEventArgs<RoundedBoxView> e) { base.OnElementChanged(e); var rbvOld = e.OldElement; if (rbvOld != null) { // Unhook any events from e.OldElement here. } var rbv = e.NewElement; if (rbv != null) { var shadowView = new UIView(); // Set properties on the UIView here. SetNativeControl(shadowView); // Hook up any events from e.NewElement here. } } } }
此呈現器中顯示的通用模式,可確保您可以在虛擬化布局(如列表視圖)中使用此模式,稍后我將對此進行討論。
如果您想要查看包含此代碼段的示例,請參閱 bit.ly/xf-customrenderer。
將屬性添加到自定義視圖您可以將屬性添加到自定義視圖,但要確保這些屬性可綁定,以便您可以將屬性綁定到視圖模型中的屬性或其他類型的數據。下面是一個 RoundedBoxView 自定義視圖中可綁定的屬性:
public class RoundedBoxView : BoxView { public static readonly BindableProperty CornerRadiusProperty = BindableProperty.Create<RoundedBoxView, double>(p => p.CornerRadius, 0); public double CornerRadius { get { return (double)base.GetValue(CornerRadiusProperty);} set { base.SetValue(CornerRadiusProperty, value);} } }
若要將新屬性連接到您的呈現器,請重寫呈現器的 OnElementPropertyChanged 方法,并添加在屬性更改時運行的代碼:
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); if (e.PropertyName == RoundedBoxView.CornerRadiusProperty.PropertyName) childView.Layer.CornerRadius = (float)this.Element.CornerRadius; }
若要了解有關創建自定義視圖和自定義呈現器的詳細信息,請參閱 bit.ly/11pSFhL 上的“自定義每個平臺的控件”。
我已經展示了幾個元素,但還有更多。這是介紹這些元素的好時機。
Xamarin.Forms 應用包含頁面、布局和視圖。一個頁面包含一個或多個布局,一個布局包含一個或多個視圖。在 Xamarin 中使用術語視圖來描述您調用控件的習慣。總的來說,Xamarin.Forms 框架包含五種頁面類型、七種布局類型和 24 種視圖類型。通過 xamarin.com/forms,您可以獲得更多信息。稍后,我將介紹一些重要的頁面類型,但首先我將花一點時間回顧一些您可以在應用中使用的布局。Xamarin.Forms 包含四種主要布局:
StackLayout:StackLayout 在單個垂直或水平行中定位子元素。您可以嵌套 StackLayouts 來創建復雜的可視層次結構。通過使用每個子視圖的 VerticalOptions 和 Horizontal­Options 屬性,可以控制視圖在 StackLayout 中的排列方式。
網格:網格將視圖排列入行和列。此布局類似于使用 WPF 和 Silverlight 獲得的布局,但您不可以在行和列之間添加間距。通過使用網格的 RowSpacing 和 ColumnSpacing 屬性來做到這一點。
RelativeLayout:通過使用相對于其他視圖的約束,RelativeLayout 可以定位視圖。
AbsoluteLayout:AbsoluteLayout 可以通過兩種方式定位子視圖:絕對位置定位或相對于父級按比例定位。這有助于創建拆分并疊加層次結構。圖 7 顯示了一個示例。
圖 7 使用 AbsoluteLayout
void AbsoluteLayoutView() { var layout = new AbsoluteLayout(); var leftHalfOfLayoutChild = new BoxView { Color = Color.Red }; var centerAutomaticallySizedChild = new BoxView { Color = Color.Green }; var absolutelyPositionedChild = new BoxView { Color = Color.Blue }; layout.Children.Add(leftHalfOfLayoutChild, new Rectangle(0, 0, 0.5, 1), AbsoluteLayoutFlags.All); layout.Children.Add(centerAutomaticallySizedChild, new Rectangle( 0.5, 0.5, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize), AbsoluteLayoutFlags.PositionProportional); layout.Children.Add( absolutelyPositionedChild, new Rectangle(10, 20, 30, 40)); }
請注意,所有布局都為您提供了名為 Children 的屬性。該屬性可用于訪問其他成員。例如,可以使用網格布局的 Children 屬性來添加和刪除行和列,以及指定行和列間距。
通過使用列表視圖窗體(名為 ListView),可以在滾動列表中顯示數據。此視圖性能良好,因為列表中每個單元格的呈現器均被虛擬化。由于每個單元格均被虛擬化,因此通過使用與前面類似的模式,正確處理為單元格或列表創建的任何自定義呈現器的 OnElementChanged 事件是非常重要的。
首先,定義某一單元格,如圖 8 中所示。ListView 的所有數據模板都必須都使用單元格作為根元素。
圖 8 定義 ListView 單元格
public class MyCell : ViewCell { public MyCell() { var nameLabel = new Label(); nameLabel.SetBinding(Label.TextProperty, "Name"); var descLabel = new Label(); descLabel.SetBinding(Label.TextProperty, "Description"); View = new StackLayout { VerticalOptions = LayoutOptions.Center, Children = { nameLabel, descLabel } }; } }
接下來,定義數據源,并對新的數據模板設置 ListView 的 ItemTemplate 屬性。數據模板基于前面創建的 MyCell 類:
var items = new[] { new { Name = "Flower", Description = "A lovely pot of flowers." }, new { Name = "Tuna", Description = "A can of tuna!" }, // ... Add more items }; var listView = new ListView { ItemsSource = items, ItemTemplate = new DataTemplate(typeof(MyCell)) };
您可以借助以下標記在 XAML 中執行此操作:
<ListView ItemsSource="{Binding Items}"> <ListView.ItemTemplate> <ViewCell> <StackLayout VerticalOptions="center"> <Label Text="{Binding Name}" /> <Label Text="{Binding Description}" /> </StackLayout> </ViewCell> </ListView.ItemTemplate> </ListView>
大多數應用包含多個頁面,因此您需要使用戶能夠從一個頁面導航到另一個頁面。以下頁面具有適用于頁面導航的內置支持,并支持全屏模式頁面演示文稿:
TabbedPage
MasterDetailPage
NavigationPage
CarouselPage
您可以將頁面作為子級添加到這四個頁面的任何一個,并免費獲得導航。
Tabbed Page TabbedPage 橫跨屏幕頂部顯示選項卡的數組。假設 PCL 項目包含名為 LogInPage、DirectoryPage 和 AboutPage 的頁面,則可以使用以下代碼將這些頁面全部添加到 TabbedPage:
var tabbedPage = new TabbedPage { Children = { new LoginPage { Title = "Login", Icon = "login.png" }, new DirectoryPage { Title = "Directory", Icon = "directory.png" }, new AboutPage { Title = "About", Icon = "about.png" } } };
在這種情況下,設置每個頁面的標題和圖標屬性是非常重要的,這可以使某些內容顯示在頁面選項卡上。并非所有平臺都呈現圖標。這取決于平臺的選項卡設計。
如果您在移動設備上打開此頁面,第一個選項卡將顯示為選中狀態。但是,可以通過設置 TabbedPage 頁面的 CurrentPage 屬性更改此狀態。
NavigationPageNavigationPage 管理大量頁面的導航和 UX。此頁為您提供了最常見的移動應用導航模式類型。下面是如何向它添加您的頁面:
var loginPage = new LoginPage(); var navigationPage = new NavigationPage(loginPage); loginPage.LoginSuccessful += async (o, e) => await navigationPage.PushAsync(new DirectoryPage());
請注意,PushAsync 方法用于導航用戶到特定頁面(在本例中為 DirectoryPage)。在 NavigationPage 中,可以將頁面“推送”到堆棧,然后在用戶向后導航到先前頁面時將其“彈出”。
NavigationPage 的 PushAsync 和 PopAsync 方法是異步的,因此您的代碼應等待它們,而不是運行任務時推送或彈出任何新頁面。推送或彈出的動畫完成后,返回每種方法的任務。
為方便起見,所有 Xamarin.Forms 視圖、布局和頁面都包含導航屬性。此屬性是一個代理接口,包含 NavigationPage 實例的 PushAsync 和 PopAsync 方法。該屬性可用于導航到頁面而不是直接調用 NavigationPage 實例的 PushAsync 和 PopAsync 方法。NavigationProperty 還可用于獲取 PushModalAsync 和 PopModalAsync 方法。這有助于將整個屏幕的內容替換為新的模式頁面。視圖的父堆棧中不一定必須有一個 NavigationPage 來使用視圖的導航屬性,但無模式 PushAsync/PopAsync 操作可能會失敗。
關于設計模式的注釋通常,將 NavigationPages 作為子級添加到 TabbedPages,將 TabbedPages 作為子級添加到 MasterDetailPages。某些類型的模式可能會導致意外的 UX。例如,大多數平臺建議您不要將 TabbedPage 添加為 NavigationPage 的子級。
有兩種方法對頁面上的視圖設置動畫效果,來創建更具吸引力的用戶體驗。選擇 Xamarin.Forms 附帶的內置動畫,或通過使用動畫 API 自己構建。
例如,您可以通過調用一個視圖的 FadeTo 動畫創建淡化效果。FadeTo 動畫內置于視圖中,因此簡單易用:
async Task SpinAndFadeView(View view) { await view.FadeTo(20, length: 200, easing: Easing.CubicInOut); }
可以通過使用 await 關鍵字一起鏈接一系列的動畫。在前一個完成后,將執行每個動畫。例如,可以在將視圖淡化為焦點之前對其進行旋轉:
async Task SpinAndFadeView(View view) { await view.RotateTo(180); await view.FadeTo(20, length: 200, easing: Easing.CubicInOut); }
如果在實現所需效果時遇到問題,可以使用完整的動畫 API。在下面的代碼中,通過旋轉視圖淡化一半:
void SpinAndFadeView(View view) { var animation = new Animation(); animation.Add(0, 1, new Animation( d => view.Rotation = d, 0, 180, Easing.CubicInOut)); animation.Add(0.5, 1, new Animation( d => view.Opacity = d, 1, 0, Easing.Linear)); animation.Commit(view, "FadeAndRotate", length: 250); }
此示例將每個動畫組合成單個動畫實例,然后使用 Commit 方法運行整個動畫序列。因為此動畫不能局限于特定視圖,所以您可以將此動畫應用于任何視圖。
Xamarin.Forms 是構建跨平臺本機移動應用的令人激動的新方法。使用它可以構建跨 iOS、Android 和 Windows Phone 本機呈現的 UI。您可以在平臺之間共享幾乎所有代碼。
Xamarin Inc. 構建 Xamarin 和 Xamarin.Forms,使 C# 開發人員幾乎能夠迅速跳轉到移動開發。如果您已經為 Windows 運行時、WPF 或 Silverlight 進行開發,您會發現 Xamarin.Forms 是跨平臺本機移動開發領域的便捷橋梁。您可以立即安裝 Xamarin 并立即開始使用 C#,以構建在 iOS、Android 和 Windows Phone 設備上運行的美觀本機應用。
看完上述內容,你們對如何借助Xamarin.Forms跨移動平臺共享UI代碼有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。