如果你像我一样,当你准备开始编写一个新的应用程序时,你面临这个问题,“Xamarin Native或Xamarin.Forms?”唯一正确的答案应该是“是”。 其实我想告诉你,这根本不应该是一个选择; 您只需开始编码,就完全有信心你走在正确的道路上。
介绍Xamarin.Forms嵌入
在Microsoft Build 2017上,我们,可以使用任何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=""
-
xmlns:x=""
-
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上获得:
您可以看到,您可以从Xamarin.iOS,Xamarin.Android和UWP开始,并在任何有益于您的地方引入Xamarin.Forms。 或者您可以从Xamarin.Forms开始,最终迁移到Xamarin.iOS,Xamarin.Android,UWP以及其他XAMarin.Forms将来带给您的任何地方。 现在你可以做更多的事情,用更好的方式使用你的代码!
这是一个预览功能,所以我们需要你的反馈! 加入我们的论坛,请与我们分享您的经验。