如果你像我一样,当你准备开始编写一个新的应用程序时,你面临这个问题,“Xamarin Native或Xamarin.Forms?”唯一正确的答案应该是“是”。 其实我想告诉你,这根本不应该是一个选择; 您只需开始编码,就完全有信心你走在正确的道路上。
介绍Xamarin.Forms嵌入
在Microsoft Build 2017上,我们发布了Xamarin.Forms Embedding,可以使用任何ContentPage并将其添加到您的本机应用程序。
其核心是XAMarin.Forms是一个共享的UI工具包,使您能够编写一个单一的UI来定位Android,iOS和UWP。 它还提供服务,以支持快速的应用程序开发,如导航,依赖关系管理和消息传递。 因此,您可以将整个应用程序写入Xamarin.Forms,而不需要触摸底层的本机OS层。 但是有一个底层!
Xamarin.Forms建立在Xamarin.iOS和Xamarin.Android基础之上,Xamarin.Android是用于生产具有100%访问平台API的高性能本机应用程序的最佳解决方案。
让我们来看看iOS的外观。
将Xamarin.Forms页面添加到Xamarin.iOS
过去一个月,我的家乡圣路易斯的天气一直是一个很大的故事,严重的雨水和淹水,所以我很痴迷户外活动。 看看Xamarin天气示例应用程序,您会看到我们有Android,iOS和UWP本机应用程序。
虽然搜索专案很好,我想存储搜索记录并比较位置。 我将向您展示我是如何在iOS上进行的,并在所有三个平台上使用Xamarin.Forms进行共享。
我添加了一个新的共享项目(或PCL)来托管Xamarin.Forms页面。 作为附注,您可以将ContentPage直接插入到您的本机项目中,并使用XAML为您的UI编写整个Xamarin本机应用程序。
Xamarin.Forms项目和每个平台项目都需要参考Xamarin.Forms 3.0早期版本的发行版。 在新的共享项目中,我有我的HistoryPage.xaml和(为了演示简单)我设置了我的BindingContext到页面。 MVVM模式也可以在这里工作得很好。
当你审查这个XAML,你会注意到这里没有什么特别的; 没有什么不同,如果这是一个Xamarin.Forms应用程序从上到下。 这个XAML现在在Xamarin处处可见。 这是强大的!
点击(此处)折叠或打开
- ?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="Weather.Forms.HistoryPage">
- Grid BackgroundColor="#002050">
- Image Source="buildheader.jpg" VerticalOptions="Start" />
- StackLayout VerticalOptions="Fill">
- StackLayout.Margin>
- OnIdiom x:TypeArguments="Thickness">
- OnIdiom.Phone>
- OnPlatform x:TypeArguments="Thickness">
- On Platform="iOS" Value="10,80,10,10">/On>
- On Platform="WinRT, UWP, Android" Value="10">/On>
- /OnPlatform>
- /OnIdiom.Phone>
- OnIdiom.Tablet>
- OnPlatform x:TypeArguments="Thickness">
- On Platform="iOS" Value="10,80,10,10">/On>
- On Platform="WinRT, UWP, Android" Value="10">/On>
- /OnPlatform>
- /OnIdiom.Tablet>
- OnIdiom.Desktop>
- OnPlatform x:TypeArguments="Thickness">
- On Platform="WinRT, UWP" Value="20">/On>
- /OnPlatform>
- /OnIdiom.Desktop>
- /OnIdiom>
- /StackLayout.Margin>
- BoxView HeightRequest="120"/>
- Label Text="Your Places">
- Label.TextColor>
- OnPlatform x:TypeArguments="Color">
- On Platform="Android" Value="GhostWhite">/On>
- On Platform="UWP, iOS" Value="White">/On>
- /OnPlatform>
- /Label.TextColor>
- Label.FontSize>
- OnPlatform x:TypeArguments="x:Double">
- On Platform="iOS" Value="24">/On>
- On Platform="WinRT, UWP, Android" Value="18">/On>
- /OnPlatform>
- /Label.FontSize>
- /Label>
- ListView x:Name="HistoryItems" VerticalOptions="Fill" BackgroundColor="Transparent">
- ListView.ItemTemplate>
- DataTemplate>
- ViewCell>
- Grid>
- Grid.ColumnDefinitions>
- ColumnDefinition Width="50">/ColumnDefinition>
- ColumnDefinition>/ColumnDefinition>
- ColumnDefinition Width="100">/ColumnDefinition>
- /Grid.ColumnDefinitions>
- Label Text="{Binding WeatherIcon}" FontSize="18" Grid.Column="0" VerticalTextAlignment="Center" TextColor="White">
- Label.FontFamily>
- OnPlatform x:TypeArguments="x:String">
- On Platform="UWP" Value="/Assets/WeatherIcons.ttf#Weather Icons">/On>
- On Platform="iOS" Value="Weather Icons">/On>
- On Platform="Android" Value="WeatherIcons.ttf#Weather Icons">/On>
- /OnPlatform>
- /Label.FontFamily>
- /Label>
- Label Text="{Binding LocationName}" Grid.Column="1" VerticalOptions="Center" TextColor="White">
- Label.FontSize>
- OnPlatform x:TypeArguments="x:Double">
- On Platform="iOS" Value="18">/On>
- On Platform="WinRT, UWP, Android" Value="14">/On>
- /OnPlatform>
- /Label.FontSize>
- /Label>
- Label Text="{Binding PostalCode}" VerticalOptions="Center" TextColor="White" Grid.Column="2" VerticalTextAlignment="Center">
- Label.FontSize>
- OnPlatform x:TypeArguments="x:Double">
- On Platform="iOS" Value="18">/On>
- On Platform="WinRT, UWP, Android" Value="14">/On>
- /OnPlatform>
- /Label.FontSize>
- /Label>
-
- /Grid>
- /ViewCell>
- /DataTemplate>
- /ListView.ItemTemplate>
- /ListView>
- StackLayout Orientation="Horizontal" HorizontalOptions="Center">
- Label Text="{Binding PlatformName}" TextColor="White" VerticalTextAlignment="Center">
- Label.FontSize>
- OnPlatform x:TypeArguments="x:Double">
- On Platform="iOS" Value="24">/On>
- On Platform="WinRT, UWP, Android" Value="18">/On>
- /OnPlatform>
- /Label.FontSize>
- /Label>
- Label TextColor="Red" VerticalTextAlignment="Center">
- Label.Text>
- OnPlatform x:TypeArguments="x:String">
- On Platform="UWP" Value="">/On>
- On Platform="iOS" Value="">/On>
- On Platform="Android" Value="">/On>
- /OnPlatform>
- /Label.Text>
- Label.FontSize>
- OnPlatform x:TypeArguments="x:Double">
- On Platform="iOS" Value="24">/On>
- On Platform="WinRT, UWP, Android" Value="18">/On>
- /OnPlatform>
- /Label.FontSize>
- Label.FontFamily>
- OnPlatform x:TypeArguments="x:String">
- On Platform="UWP" Value="Segoe MDL2 Assets">/On>
- On Platform="iOS" Value="FontAwesome">/On>
- On Platform="Android" Value="FontAwesome.otf#FontAwesome">/On>
- /OnPlatform>
- /Label.FontFamily>
- /Label>
- Label Text=" Xamarin.Forms" VerticalTextAlignment="Center" TextColor="White">
- Label.FontSize>
- OnPlatform x:TypeArguments="x:Double">
- On Platform="iOS" Value="24">/On>
- On Platform="WinRT, UWP, Android" Value="18">/On>
- /OnPlatform>
- /Label.FontSize>
- /Label>
- /StackLayout>
-
-
- /StackLayout>
- /Grid>
- /ContentPage>
您可以期待您充分利用图像和自定义字体。 在代码中,您将看到可以使用XAML编译器来预编译XAML,MessagingCenter进行消息传递,并且所有数据绑定都可以正常工作。
点击(此处)折叠或打开
- [XamlCompilation(XamlCompilationOptions.Compile)]
- public partial class HistoryPage : ContentPage
- {
- public const string HistoryItemSelected = "HistoryItemSelected";
-
- public HistoryPage()
- {
- InitializeComponent();
-
- HistoryItems.ItemsSource = HistoryRecorder.LocationHistory;
- HistoryItems.ItemTapped += HistoryItemsOnItemTapped;
-
- BindingContext = this;
- }
-
- public string PlatformName => $"{Device.RuntimePlatform} ";
-
- private void HistoryItemsOnItemTapped(object sender, ItemTappedEventArgs itemTappedEventArgs)
- {
- var historyItem = itemTappedEventArgs.Item as HistoryItem;
-
- if (historyItem == null)
- {
- return;
- }
-
- MessagingCenter.Send(this, HistoryItemSelected, historyItem.PostalCode);
- }
- }
要在Xamarin.iOS应用程序中使用HistoryPage,我现在只需要做两件事情:
- 用Forms.Init()初始化窗体。
- 将页面添加到我的视图。
注意方法CreateViewController()的返回值是UIViewController。 从这一点开始,您与本地控件的交互方式遵循相同的规则,就像您从一开始就将其定义为UIViewController一样 - 因为您已经做到了! 在Android上CreateFragment(* Context *)返回本机片段,而在UWP上CreateFrameworkElement()返回本机的FrameworkElement。
下一步是什么
在您的帮助下,我们将继续验证我们的实施,并确保它们都按需要工作。 在Xamarin.Forms的非UI部分中,NavigationService不受Xamarin.Forms应用程序的支持,而DependencyService和MessagingCenter完全可以运行。
这里还有待完成的工作。 现在,ContentPage完全支持,但我们也认为我们可以在控件(和自定义控件)级别执行此操作。 我们需要仔细查看Application.Resources和共享样式。 我们还在查看我们的模板和IDE支持,使其易于使用Xamarin.Forms无处不在。
今天开始嵌入!
嵌入的Xamarin.Forms 3.0预览已发布到自定义的NuGet Feed。 为拿到它,为实现它:
- 向NuGet管理器添加新的源代码:https://www.myget.org/F/xamarinforms-dev/api/v3/index.json
- 选中预发行
- 选择并安装功能名称为“Embedding”的软件包 - 3.0.0.100-embeddingpreview
该天气演示应用程序代码的来源可在GitHub上获得:https://github.com/davidortinau/build2017-new-in-xamarin-forms
您可以看到,您可以从Xamarin.iOS,Xamarin.Android和UWP开始,并在任何有益于您的地方引入Xamarin.Forms。 或者您可以从Xamarin.Forms开始,最终迁移到Xamarin.iOS,Xamarin.Android,UWP以及其他XAMarin.Forms将来带给您的任何地方。 现在你可以做更多的事情,用更好的方式使用你的代码!
这是一个预览功能,所以我们需要你的反馈! 加入我们的论坛,请与我们分享您的经验。