编辑的区别
您可能认为编辑器具有比Entry更广泛的API,因为它可以处理多行甚至文本段落。 但在Xamarin.Forms中,编辑器API实际上更简单一些。 除了从InputView继承Keyboard属性之外,Editor还自己定义了一个属性:基本的Text属性。 编辑器还定义了与Entry相同的两个事件:
- TextChanged
- Completed
但是,已完成的活动必然会有所不同。虽然return或enter键可以表示条目的完成,但是与编辑器一起使用的这些相同的键代替标记段落的结尾。
Editor的Completed事件在三个平台上的工作方式略有不同:对于iOS,Xamarin.Forms在键盘上方显示一个特殊的Done按钮,用于解除键盘并导致Completed事件触发。在Android和Windows 10 Mobile上,系统后退按钮 - 纵向模式下手机左下角的按钮 - 取消键盘并触发已完成事件。此“返回”按钮不会为“条目”视图触发“已完成”事件,但它会关闭键盘。
用户输入编辑器的内容可能不是电话号码和URL,而是实际的单词,句子和段落。在大多数情况下,您需要使用文本键盘编辑器,因为它提供拼写检查,建议和句子的第一个单词的自动大写。如果您不想要这些功能,Keyboard类提供了另一种使用静态Create方法和KeyboardFlags枚举的以下成员指定键盘的方法:
- CapitalizeSentence (equal to 1)
- Spellcheck (2)
- Suggestions (4)
- All (xFFFFFFFF)
Text键盘相当于使用KeyboardFlags.All创建键盘。 默认键盘相当于使用(KeyboardFlags)0创建键盘。 您无法使用这些标志在XAML中创建键盘。 它必须在代码中完成。
JustNotes程序旨在作为一个自由形式的笔记记录程序,通过使用Application类的Properties集合自动保存和恢复Editor视图的内容。 该页面基本上由一个大型编辑器组成,但为了给用户一些关于程序功能的线索,程序的名称显示在顶部。 在iOS和Android上,可以通过页面的Title属性设置此类文本,但要显示该属性,ContentPage必须包装在ApplicationPage中(正如您在第13章中使用ToolbarDemo程序所发现的那样)。 这是在App类的构造函数中完成的:
public class App : Application
{
public App()
{
MainPage = new NavigationPage(new JustNotesPage());
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
((JustNotesPage)(((NavigationPage)MainPage).CurrentPage)).OnSleep();
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
App中的OnSleep方法调用JustNotesPage代码隐藏文件中定义的名为OnSleep的方法。 这是编辑器的内容保存在应用程序内存中的方式。
XAML页面的根元素设置Title属性。 页面的其余部分由填充了编辑器的AbsoluteLayout占用:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="JustNotes.JustNotesPage"
Title="Just Notes">
<StackLayout>
<AbsoluteLayout VerticalOptions="FillAndExpand">
<Editor x:Name="editor"
Keyboard="Text"
AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
AbsoluteLayout.LayoutFlags="All"
Focused="OnEditorFocused"
Unfocused="OnEditorUnfocused" />
</AbsoluteLayout>
</StackLayout>
</ContentPage>
那么为什么程序使用AbsoluteLayout来托管编辑器呢?
JustNotes计划正在进行中。 它不适合iOS。 您可以回想一下,当Entry视图位于屏幕底部时,您希望将其放在ScrollView中,以便在显示iOS虚拟键盘时向上滚动。 但是,因为Editor实现了自己的滚动,所以不能将它放在ScrollView中。
因此,当编辑器获得输入焦点以使键盘不与其重叠时,代码隐藏文件将编辑器的高度设置为AbsoluteLayout高度的一半,并在输入丢失时恢复编辑器高度 焦点:
public partial class JustNotesPage : ContentPage
{
public JustNotesPage()
{
InitializeComponent();
// Retrieve last saved Editor text.
IDictionary<string, object> properties = Application.Current.Properties;
if (properties.ContainsKey("text"))
{
editor.Text = (string)properties["text"];
}
}
void OnEditorFocused(object sender, FocusEventArgs args)
{
if (Device.OS == TargetPlatform.iOS)
{
AbsoluteLayout.SetLayoutBounds(editor, new Rectangle(0, 0, 1, 0.5));
}
}
void OnEditorUnfocused(object sender, FocusEventArgs args)
{
if (Device.OS == TargetPlatform.iOS)
{
AbsoluteLayout.SetLayoutBounds(editor, new Rectangle(0, 0, 1, 1));
}
}
public void OnSleep()
{
// Save Editor text.
Application.Current.Properties["text"] = editor.Text;
}
}
当然,这种调整只是近似的。 它因设备而异,并且因纵向和横向模式而异,但目前Xamarin.Forms中没有足够的信息可以更准确地完成。 目前,您可能应该将编辑器视图的使用限制在页面的顶部区域。
与编辑器操作相比,保存和恢复编辑器内容的代码相当平淡无奇。 OnSleep方法(从App类调用)使用“text”键将属性字典中的文本保存,构造函数将其恢复。
这是在所有三个平台上运行的程序,文本键盘在视图中提供了单词建议。 在Windows 10 Mobile屏幕上,已选择一个单词,可能会将其复制到剪贴板以便以后进行粘贴操作: