Xamarin.Forms入门

概述:最近我一直在学习Xamarin相关的知识,在这个过程中,我碰到了一些问题,然后尝试了很多方法来解决它们。为了让刚接触到Xamarin的开发人员避免花过多的时间在这些同样的问题上,我想把我的一些心得体会分享给大家。
 

Xamarin.Forms介绍

1. 为什么使用Xamarin.Forms

提到开发移动应用,一般我们想到的是用Objective-C, Java,Swift这些语言来开发。对于一些.Net开发人员来说,学习一门新语言当然会花费额外的时间精力。特别是当我们想要同时开发安卓和苹果应用的时候,我们需要学习好几种技术。Xamarin正好解决了.Net开发人员的烦恼。Xamarin只需要会使用C#语言,就可以开发在众多平台包括iOS, Android,Windows Phone都能运行的原生应用。Xamarin由Xamarin.iOS,Xamarin.Android,Xamarin.Forms组成。接下来我会详细介绍Xamarin.Forms的相关内容。

2. Xamarin.Forms是什么

Xamarin.Forms是一个跨平台的框架,允许开发人员开发一套可以被Android,iOS,Windows,Windows Phone共享的用户界面。用户界面会根据每个平台来用原生的控件渲染。对于不同的平台,Xamarin.Forms会保持原生的界面外观。在写Xamarin.Forms应用的时候,大量代码可以写在共享代码里,每个平台特有的代码就分别写在每个平台里。处理共享代码的方式有两种。一种是使用可移植类库,另一种是使用共享工程。在可移植类库里,当代码编译后,每个平台会生成相应的程序集。在共享工程里,大量不同的程序工程可以引用共同的代码。创建用户界面也有两种方式。一种是使用C#代码,另一种是使用可扩展应用程序标记语言。所以对于有WPF开发经验的人来说,Xamarin.Forms很容易入门。尽管Xamarin.Forms的控件已经足够了,我们还是可以通过渲染在每个平台创建不同的控件。

3. 移动应用和桌面应用的不同之处

我们可以看到手机应用和桌面应用有很多不同之处。对于刚接触移动开发的开发人员来说,最好是改变原来做桌面应用的视角和习惯。例如在桌面应用中,我们习惯使用复选框来表示选项,而在移动应用中,更多地使用“开关”控件。除了控件样式不太相同,用户行为也不相同。触摸屏幕取代了点击鼠标。
 

用Xamarin.Forms创建应用

1.创建一个Xamarin.Forms项目

 

2.Xamarin.Forms项目架构

<1> 可移植类库(PCL) 这一层存放共享代码,我们可以添加可扩展应用程序标记语言页面来实现用户界面。
<2> 特定的平台 (Android, iOS, Windows, WinPhone) 对于每一个平台,我们可以添加特定的功能例如开机画面等。

3.显示 “Hello Xamarin”

<1>在HelloPage.xaml里添加一个内容为“Hello Xamarin”的标签
 
 
<2>在App.cs里设置HelloPage为MainPage
 

 

4.在模拟器上运行应用

我们可以使用Visual Studio自带的模拟器,也可以使用Genymotion来运行应用。Genymotion要比默认的模拟器更快一些
 

控件

Xamarin.Forms有如下四种主要的控件组:

1.页面

Xamarin.Forms支持 ContentPage, MasterDetailPage, NavigationPage, TabbedPage, TemplatedPage, CarouselPage。ContentPage指一个页面只显示一个单独的视图。 MasterDetailPage指一个页面可以管理两个信息板块。NavigationPage指一个页面可以管理一系列页面的跳转。TabbedPage指一个页面通过标签来切换子页面。TemplatedPage指一个页面用一个控件模板来显示全屏内容。CarouselPage指一个页面允许像图库似地滑动子页面。

2. 布局

Xamarin.Forms支持ContentPresenter, ContentView, Frame, ScrollView, TemplatedView, AbsoluteLayout, Grid, RelativeLayout, StackLayout。ContentPresenter用来管理模板视图的布局,用在ControlTemplate中来标记显示内容的位置。ContentView指包含一个单独内容的元素。 Frame指包含一个单独子元素的元素。ScrollView指一个元素可以滚动它的内容。TemplatedView指一个元素用一个控件模板来显示内容。AbsoluteLayout指该布局中的元素在绝对位置。Grid指一个布局以行和列来显示元素。RelativeLayout指该布局中的元素在相对位置。StackLayout指该布局中的元素水平地排成一行或垂直地排成一列。

3.视图

Xamarin.Forms支持ActivityIndicator, BoxView, Button, DatePicker, Editor, Entry, Image, Label, ListView, OpenGLView, Picker, ProgressBar, SearchBar, Slider, Stepper, Switch, TableView, TimePicker, WebView。ActivityIndicator 指加载控件。 BoxView指一个实心的色块。 Editor is是一个多行的文本框。 Entry是一个单行的文本框。OpenGLView是用来显示OpenGL内容的控件。 Picker是用来显示数据列表以供选择的控件。 Stepper是用来输入一定范围内的离散数值的控件。Switch 是一个像开关一样的控件。 WebView是用来显示HTML内容的控件。
 

4.单元格

Xamarin.Forms支持EntryCell, SwitchCell, TextCell, ImageCell。EntryCell指一个包含标签和单行文本框的单元格。SwitchCell指一个包含一个标签和一个开关的单元格。TextCell指一个包含第一级和第二级文本的单元格。 ImageCell指一个包含图片的单元格。

 

自定义控件

有时我们可能想要更换控件的样式或行为,例如背景色,输入类型等等。自定义控件提供了这样一种方式来自定义Xamarin.Forms控件的外观行为。在每个平台里,每个控件都被渲染成不同的样式。
 
操作如下:
 
1.在PCL项目里创建自定义控件
 
public class CustomPicker : Picker
{
}

2.在Droid项目里创建渲染子类来继承相关的渲染类,重写OnElementChanged方法来实现自定义样式。

[assembly:ExportRenderer(typeof(CustomPicker),typeof(CustomPickerRenderer))]
namespace App.Droid
{
    public class CustomPickerRenderer : PickerRenderer
    {
protected override void OnElementChanged(ElementChangedEventArgs e)
      {
            base.OnElementChanged(e);
            Control.InputType = InputTypes.TextFlagNoSuggestions;
       }
}

 

页面导航

NavigationPage提供了一种层次导航,通过这种方式能让用户感受到页面间的导航,向前或退后。NavigationPage用栈的结构来管理一系列页面的导航。在导航栈中添加的第一个页面被称为根页面。
public App()
     {
         MainPage = new NavigationPage(new FirstPage());
     }

FirstPage被添加到导航栈中,成为根页面。

如果你想添加第二个页面到导航栈中,你可以使用Navigation.PushAsync(new SecondPage())。
 
如果你想从导航栈中移除当前页面,你可以使用Navigation.PopAsync()。

 

Xamarin.Forms性能

在开发移动应用的时候,有一件事应该引起开发人员的重视,那就是应用的性能。性能差会使应用反应迟钝,导致缓慢滚动,甚至会减少电池寿命。有许多方法能提升应用的性能,以下是一些建议:

1.选择正确的布局

避免使用RelativeLayout,因为它会使CPU处理更多的工作。优先选择Grid布局,而不要使用StackLayout的组合因为会造成不必要的布局计算。还可以通过使用Margin属性来减少布局层次的深度。

2.谨慎选择第三方控件

我曾使用过DevExpress的Grid控件,不幸的是,初始化页面的时候要花5到6秒。当我改用Xamarin.Forms默认的ListView控件时,初始化页面只花了1到2秒。

3.启用XAML Compiler

XAMLC可以减少最终程序集的文件大小并且减少加载和初始化XAML元素的时间。XAMLC可以通过在程序集级别下添加如下特性来启动:[assembly:XamlCompilation(XamlCompilationOptions.Compile)]。
 
up
0 users have voted.

Add new comment