从Android 1.5开始,Android平台提供了一个输入法框架(IMF),允许创建屏幕上的输入方法,如软件键盘。本文概述了Android输入法编辑器(IME)是什么,以及应用程序需要做什么才能与它们协同工作。 IMF旨在支持新类Android设备(例如没有硬件键盘的设备),应用程序与IMF一起使用并为用户提供了极好的体验非常重要。
什么是输入法?
Android IMF旨在支持各种各样的IME,包括软键盘,手写识别器和硬键盘。然而,我们的焦点将在软键盘上,因为这是目前作为平台一部分的输入法。
A user will usually access the current IME by tapping on a text view to edit, as shown here in the home screen:
用户通常通过点击要编辑的文本视图来访问当前的IME,如主屏幕中所示:
软键盘位于应用程序窗口的屏幕底部。为了组织应用程序和IME之间的可用空间,我们使用了几种方法;这里显示的一个称为平移和扫描,只是涉及滚动应用程序窗口,以便使当前聚焦的视图是可见的。这是默认模式,因为它是现有应用程序最安全的。
最常用的首选屏幕布局是调整大小,其中应用程序的窗口调整为完全可见。此处显示了撰写电子邮件时的示例:
更改应用程序窗口的大小,使其不会被IME隐藏,从而允许完全访问应用程序和IME。这当然只适用于具有可缩小区域的应用程序,该区域可以减小以获得足够的空间,但是此模式下的垂直空间实际上不比横屏方向上的可用空间小,因此应用程序通常已经可以容纳它。
最后一个主要模式是全屏或提取模式。当IME太大而无法与底层应用程序合理共享空间时使用。使用标准IME,只会在屏幕是横向的情况下遇到这种情况,虽然IME能像它们希望的那样随意使用。在这种情况,应用的窗口保持原样,IME以全屏方式显示到顶端,如下所示:
因为IME覆盖了应用程序,所以它有自己的编辑区域,它显示应用程序中实际包含的文本。还有一些有限的机会,应用程序必须定制IME的部分(顶部的“完成”按钮,并在底部enter 按键按钮),以改善用户体验。
用于控制IME的基本XML属性
系统为了尽量帮助现有应用程序尽可能与IME一起工作,做了很多事情,例如:
- 默认情况下使用平移和扫描模式,除非它可以合理地猜测调整大小模式将通过列表,滚动视图等的存在工作。
- 分析各种现有的TextView属性以猜测内容的类型(数字,纯文本等),以帮助软键盘显示适当的键布局。
- 为全屏IME分配一些默认操作,例如“next field”和“done”。
还有一些简单的事情,你可以在你的应用程序使用,这将经常大大提高其用户体验。除非明确提及,这些都可以在任何Android平台版本,即使是Android 1.5之前的版本(因为他们会忽略这些新的选项)。
为每个EditText控件指定输入类型
应用程序最重要的事情是在每个EditText上使用新的android:inputType属性。该属性提供关于文本内容的更丰富的信息。这个属性实际上取代了许多现有的属性(android:password,android:singleLine,android:numeric,android:phoneNumber,android:capitalize,android:autoText和android:editable)。如果指定较早的属性和新的android:inputType属性,系统将使用android:inputType并忽略其他属性。
android:inputType属性有三个部分:
- 类是字符的整体解释。当前支持的类是文本(纯文本),数字(十进制数),电话(电话号码)和日期时间(日期或时间)。
- 变化是对类的进一步细化。在属性中,通常将类和变量一起指定,类作为前缀。例如,textEmailAddress是一个文本字段,其中用户将输入一个电子邮件地址(foo@bar.com),因此键布局将具有容易访问的“@”字符,而numberSigned是一个带符号的数字域。如果只指定类,那么你得到默认/通用变量。
- 可以指定提供进一步细化的附加标志。这些标志特定于一个类。例如,文本类的一些标志是textCapSentences,textAutoCorrect和textMultiline。
例如,下面是IM应用程序的消息文本视图的新EditText:
<EditText android:id="@+id/edtInput"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="textShortMessage|textAutoCorrect|textCapSentences|textMultiLine"
android:imeOptions="actionSend|flagNoEnterAction"
android:maxLines="4"
android:maxLength="2000"
android:hint="@string/compose_hint"/>
所有输入类型的完整描述可以在文档中找到。重要的是使用可用的正确输入类型,以便软键盘可以为用户将要输入的文本使用最佳键盘布局。
启用调整大小模式和其他窗口功能
你的应用程序要做的第二件最重要的事情是指定窗口相对于输入法的整体行为。最可见的方面是控制调整大小与平移和扫描模式,但还有其他一些事情,你可以做,以改善用户体验。
你通常通过AndroidManifest.xml中每个定义的android:windowSoftInputMode属性来控制这个行为。与输入类型一样,有一些不同的数据,这里可以通过将它们组合在一起来指定:
- 窗口调整模式由adjustResize或adjustPan指定。强烈建议您始终指定一个或另一个。
- 您可以进一步控制是否在显示activity时自动显示IME,以及用户移动到的它时的情况。默认情况下,系统不会自动显示IME,但在某些情况下,如果应用程序启用此行为,这样可以方便用户使用。你可以使用stateVisible请求使用这个特性。还有一些其他状态选项用于更细粒度的控制,您可以在文档中找到。
此字段的典型示例可以在编辑联系人activity中看到,该activity确保其调整大小并自动显示用户的IME:
<activity name="EditContactActivity"
android:windowSoftInputMode="stateVisible|adjustResize">
...
</activity>
注意:从Android 1.5(API Level 3)开始,平台提供了一个新的方法setSoftInputMode(int),非活动窗口可以用来控制他们的行为。在您的程序中调用此方法将使您的应用程序与以前版本的Android平台不兼容。
控制操作按钮
“action”按钮是我们看到的IME的最后一个定制部分。目前有两种类型的操作:
- 当不在多行编辑文本上操作时,通常将软键盘上的输入键绑定到”action”上。例如,在G1手机上,按下硬输入键通常会移动到下一个字段,或者应用程序将拦截它以执行其它动作;使用软键盘,输入键的这种重载会被保持,因为输入按钮仅仅发送“enter”按键事件。
- 在全屏模式下,IME还可以在正在编辑的文本的右侧放置一个附加操作按钮,使用户能够快速访问常见的应用程序操作。
这些选项由TextView上的android:imeOptions属性控制。其值可以是以下值的任意组合:
- 其中一个预定义的动作常量(actionGo,actionSearch,actionSend,actionNext,actionDone)。如果没有指定这些,则系统将根据在此之后是否存在可聚焦字段来推断actionNext或actionDone;可以明确强制没有actionNone的行动。
- flagNoEnterAction选项告诉IME“action”不应该用在“enter”键上,即使文本本身不是多行的。这避免用户无意中触摸了诸如(发送)的不可恢复的动作。
- flagNoAccessoryAction从文本区域中删除“action”按钮,为文本区留出更多空间。
- flagNoExtractUi完全删除文本区域,让应用程序躲在IME的后面。
以前的IM应用程序消息视图还提供了一个有趣的使用imeOptions的示例,指定为发送操作,但不允许看见“enter”键:
android:imeOptions="actionSend|flagNoEnterAction"
用于控制IME的API
要对IME进行更高级的控制,可以使用各种新的API。除非特别小心(例如通过使用反射),使用这些API将导致您的应用程序与以前的Android版本不兼容,应该确保在AndroidManifest中指定android:minSdkVersion =“3”。有关详细信息,请参阅清单元素的文档。
主要新增的API是android.view.inputmethod.InputMethodManager类,您可以使用Context.getSystemService()得到它的实例。它允许您与全局输入法状态进行交互,例如显式隐藏或显示当前IME的输入区域。
还有一些新的窗口标志控制输入法的交互,你可以通过现有的Window.addFlags()方法和新的Window.setSoftInputMode()方法控制。 PopupWindow类已经实现了相应的方法来在其窗口上控制这些选项。特别要注意的一件事是新的WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM常量,其用于控制窗口是在当前IME的顶部还是后面。
激活的IME和应用程序之间的大多数交互是通过android.view.inputmethod.InputConnection类完成的。这是应用程序实现的API,IME调用它来对应用程序执行适当的编辑操作。通常不需要担心它,因为TextView为提供了自己的实现。
还有一些新的View的API,其中最重要的是onCreateInputConnection(),它为IME创建一个新的InputConnection(使用android.view.inputmethod.EditorInfo参数,在参数中包含输入类型,IME 选项,和另外的一些值域);再次,大多数开发人员不需要担心这一点,因为TextView会为你考虑到它。