- 輸入法編輯器(IME)是一個便于用戶輸入文本的控件膜眠。Android提供了一個可擴(kuò)展的輸入法框架籽孙,允許應(yīng)用程序提供可替代的輸入法会钝,比如屏幕上的鍵盤或者語音輸入伐蒋。在安裝輸入法后,用戶可以通過系統(tǒng)選項選擇想要使用的輸入法迁酸。
- 想要添加一個輸入法先鱼,你需要創(chuàng)建一個Android應(yīng)用并包含一個繼承自InputMethodService的類。此外奸鬓,同城創(chuàng)建一個設(shè)置頁面來承載輸入發(fā)的各個選項焙畔。你可以自行定義一個設(shè)置的UI。
下面講述以下幾個內(nèi)容:
- 輸入法的生命周期
- 在應(yīng)用的清單文件中定義輸入法組件
- 輸入法相關(guān)接口
- 設(shè)計一個款輸入法的UI
- 發(fā)送文本到應(yīng)用
- 輸入法子類型的使用
一串远、輸入法的生命周期
輸入法的生命周期如下圖所示:
20170206170754535.png
二宏多、在清單文件中定義輸入法組件
在Android系統(tǒng)中儿惫,IME是一個包含特殊IME服務(wù)的應(yīng)用程序。應(yīng)用的清單文件必須聲明輸入法服務(wù)伸但,請求必須的權(quán)限肾请,提供一個intent filter來匹配 action.view.InputMethod,并提供定義了IME特征的元數(shù)據(jù)(metadata)更胖。此外铛铁,可以定義一個設(shè)置頁面來提供用戶修改IME配置的接口,它可以被系統(tǒng)設(shè)置所啟動函喉。
- 下面的代碼片段聲明了一個IME服務(wù)避归。請求了 BIND_INPUT_METHOD 權(quán)限來允許服務(wù)連接到系統(tǒng)的IME荣月,建立intent filter和metadata:
<!-- Declares the input method service -->
<service android:name="FastInputIME"
android:label="@string/fast_input_label"
android:permission="android.permission.BIND_INPUT_METHOD">
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>
<meta-data android:name="android.view.im"
android:resource="@xml/method" />
</service>
下面的代碼片段聲明了IME的設(shè)置頁面管呵,它擁有 ACTION_MAIN 的intent filter來表示它是IME程序的主入口
<!-- Optional: an activity for controlling the IME settings -->
<activity android:name="FastInputIMESettings"
android:label="@string/fast_input_settings">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
也可以從IME的UI提供直接進(jìn)入設(shè)置的入口。
三哺窄、輸入法API
與IME相關(guān)的類在 android.inputmethodservice 和 android.view.inputmethod 包中捐下。KeyEvent 類對于處理鍵盤特征至關(guān)重要。
IME的核心部分是一個服務(wù)組件萌业,即一個繼承自InputMethodService的類坷襟。此外為了實現(xiàn)一般服務(wù)的生命周期,這個類提供了IME的UI生年,處理用戶輸入和傳輸文本到指定區(qū)域以及當(dāng)前焦點的回調(diào)婴程。InputMethodService類提供了絕大多數(shù)管理IME狀態(tài)和與當(dāng)前輸入?yún)^(qū)域交互的實現(xiàn)。
下面幾個類也很重要抱婉。
BaseInputConnection
定義了輸入法和應(yīng)用之間接收輸入的交互通道档叔。使用它來讀取光標(biāo)周圍的文本,提交文本到輸入框以及發(fā)送鍵盤事件給應(yīng)用蒸绩。應(yīng)用應(yīng)該集成此類衙四。
KeyboardView
一個View的擴(kuò)展,描繪了一個鍵盤和用戶輸入事件的響應(yīng)患亿。鍵盤的布局是被Keyboard的實例指定传蹈,可以定義一個XML文件。
四步藕、設(shè)計輸入法UI
IME有兩個主要的視覺元素:即輸入視圖和備選視圖惦界。你只需要實現(xiàn)和你設(shè)計的輸入法有關(guān)的元素。
4.1 輸入視圖
輸入視圖是用戶使用按鍵咙冗,手寫或者手勢在表單中輸入文本的UI沾歪。
當(dāng)IME第一次顯示,系統(tǒng)會調(diào)用 onCreateInputView() 回調(diào)乞娄。在你實現(xiàn)的這個方法中瞬逊,你創(chuàng)建你想要的IME窗口的布局并返回給系統(tǒng)显歧。下面片段是一個例子:
@Override
public View onCreateInputView() {
MyKeyboardView inputView =
(MyKeyboardView) getLayoutInflater().inflate( R.layout.input, null);
inputView.setOnKeyboardActionListener(this);
inputView.setKeyboard(mLatinKeyboard);
return mInputView;
}
這里的MyKeyboardView是一個自定義的實現(xiàn)了 KeyboardView 的實例,如果你構(gòu)建的是一個傳統(tǒng)的QWERTY鍵盤确镊,請查看 KeyboardView 類士骤。
4.2.候選視圖
候選視圖是供用戶選擇可選詞和推薦詞的視圖。在IME的生命周期中蕾域,系統(tǒng)在準(zhǔn)備好顯示備選視圖的時候會調(diào)用onCreateCandidatesView()拷肌。在你實現(xiàn)的這個方法中,返回顯示詞匯建議的布局旨巷,當(dāng)什么都不顯示時巨缘,返回null。
若要查看實現(xiàn)用戶建議詞匯的例子采呐,請查看SoftKeyboard示例應(yīng)用若锁。
4.3.UI設(shè)計依據(jù)
此部分介紹了一些IME的UI設(shè)計思想。
· 應(yīng)對多元化的屏幕尺寸
你的IME的UI必須可以適配不同屏幕的尺寸斧吐,且必須處理豎屏和橫屏兩種方向又固。在非全屏模式下,為應(yīng)用程序留出足夠的空間以顯示文本字段和任何相關(guān)聯(lián)的上下文煤率,使得IME不會占用屏幕一半以上的空間仰冠。在全屏模式下沒有這個問題。
· 處理不同的輸入類型
Android的輸入框允許你選擇一個特殊的輸入類型蝶糯,比如自由文本洋只,數(shù)字,網(wǎng)址昼捍,郵箱地址识虚,收索內(nèi)容等。當(dāng)你實現(xiàn)一個新的IME端三,您需要檢測每個字段的輸入類型舷礼,并為其提供適當(dāng)?shù)慕涌凇?/strong>但是,你不必設(shè)置IME以檢查用戶輸入的文本對輸入類型有效; 這是擁有文本字段的應(yīng)用程序的責(zé)任郊闯。
當(dāng)輸入字段接收焦點并且您的IME啟動時妻献,系統(tǒng)調(diào)用 onStartInputView(),傳遞一個 EditorInfo 對象团赁,該對象包含有關(guān)文本字段的輸入類型和其他屬性的詳細(xì)信息育拨。 在此對象中,inputType 字段包含文本字段的輸入類型欢摄。
輸入類型字段是一個包含用于各種輸入類型設(shè)置的位模式的int參數(shù)熬丧。 要測試它的文本字段的輸入類型,用常量TYPE_MASK_CLASS屏蔽它怀挠,像這樣:
inputType & InputType.TYPE_MASK_CLASS
輸入類型位模式可以具有幾個值中的一個析蝴,包括:
TYPE_CLASS_NUMBER
用于輸入數(shù)字的文本字段害捕。
TYPE_CLASS_DATETIME
用于輸入日期和時間的文本字段。
TYPE_CLASS_PHONE
用于輸入電話號碼的文本字段闷畸。
TYPE_CLASS_TEXT
用于輸入所有支持的字符的文本字段尝盼。
這些常量在 InputType 的參考文檔中有更詳細(xì)的描述。
inputType字段可以包含指示文本字段類型的其他位佑菩,例如:
TYPE_TEXT_VARIATION_PASSWORD
用于輸入密碼的TYPE_CLASS_TEXT 的變體盾沫。 輸入法將顯示標(biāo)記,而不是實際文本殿漠。
TYPE_TEXT_VARIATION_URI
用于輸入網(wǎng)址和其他統(tǒng)一資源標(biāo)識符(URI)的TYPE_CLASS_TEXT 的變體赴精。
TYPE_TEXT_FLAG_AUTO_COMPLETE
TYPE_CLASS_TEXT 的變體,用于輸入應(yīng)用程序從字典绞幌,搜索或其他工具中“自動完成”的文本蕾哟。
記住在測試這些變量時,用適當(dāng)?shù)某?shù)掩蔽輸入類型啊奄。 可用的掩碼常數(shù)在輸入類型的參考文檔中列出渐苏。
注意:在您自己的IME中掀潮,確保在將其發(fā)送到密碼字段時正確處理文本菇夸。 在輸入視圖和候選視圖中的用戶界面中隱藏密碼。 還要記住仪吧,您不應(yīng)該在設(shè)備上存儲密碼庄新。 要了解更多信息,請參閱“為安全性設(shè)計”指南薯鼠。
五择诈、向應(yīng)用程序發(fā)送文本
當(dāng)用戶使用IME輸入文本時,您可以通過發(fā)送單個鍵事件或在應(yīng)用程序的文本字段中編輯光標(biāo)周圍的文本來向應(yīng)用程序發(fā)送文本出皇。 在任一情況下羞芍,您都使用 InputConnection
的實例來傳遞文本。 要獲取此實例郊艘,請調(diào)用 InputMethodService.getCurrentInputConnection() 荷科。
5.1.編輯光標(biāo)周圍的文本
當(dāng)處理文本字段中現(xiàn)有文本的編輯時,BaseInputConnection 中一些更有用的方法是:
getTextBeforeCursor()
返回包含當(dāng)前光標(biāo)位置之前的請求字符數(shù)的 CharSequence 纱注。
getTextAfterCursor()
返回包含當(dāng)前光標(biāo)位置后的請求字符數(shù)的 CharSequence 畏浆。
deleteSurroundingText()
刪除當(dāng)前光標(biāo)位置前后的指定數(shù)量的字符。
commitText()
向文本字段提交 CharSequence 并設(shè)置新的光標(biāo)位置狞贱。
例如刻获,以下代碼段顯示如何使用文本“Hello!”替換光標(biāo)左側(cè)的四個字符:
InputConnection ic = getCurrentInputConnection();
ic.deleteSurroundingText(4, 0);
ic.commitText("Hello", 1);
ic.commitText("!", 1);
5.2.在提交之前撰寫文本
如果您的IME執(zhí)行文本預(yù)測或需要多個步驟來組成字形或單詞瞎嬉,則可以在文本字段中顯示進(jìn)度蝎毡,直到用戶提交單詞厚柳,然后您可以用完成的文本替換部分組合。 當(dāng)你傳遞給 setComposingText()時沐兵,你可以通過添加一個“span”來對文本進(jìn)行特殊處理草娜。
以下代碼段顯示了如何在文本字段中顯示進(jìn)度
2.在提交之前撰寫文本
如果您的IME執(zhí)行文本預(yù)測或需要多個步驟來組成字形或單詞,則可以在文本字段中顯示進(jìn)度痒筒,直到用戶提交單詞宰闰,然后您可以用完成的文本替換部分組合。 當(dāng)你傳遞給 setComposingText()時簿透,你可以通過添加一個“span”來對文本進(jìn)行特殊處理移袍。
以下代碼段顯示了如何在文本字段中顯示進(jìn)度
以下屏幕截圖顯示了用戶看到的頁面:
5.3.攔截硬件按鍵事件
即使輸入法窗口沒有明確的焦點,它首先接收硬件鍵事件老充,并且可以選擇使用它們或?qū)⑺鼈冝D(zhuǎn)發(fā)到應(yīng)用程序葡盗。 例如,您可能想要使用方向鍵在UI中導(dǎo)航以在組合期間選擇候選項啡浊。 您可能還想捕獲返回鍵以關(guān)閉源自輸入法窗口的任何彈出窗口觅够。
要攔截硬件鍵,重寫onKeyDown()和 onKeyUp()巷嚣。 請參閱 SoftKeyboard 示例應(yīng)用程序的示例喘先。
記住要為你不想處理的鍵調(diào)用super()方法。
六廷粒、創(chuàng)建IME子類型
子類型允許IME公開IME支持的多種輸入模式和語言窘拯。 子類型可以表示:
· 區(qū)域設(shè)置,如en_US或fr_FR
· 輸入模式坝茎,如語音涤姊,鍵盤或手寫
· IME特有的其他輸入樣式,表單或?qū)傩脏头牛?0鍵或qwerty鍵盤布局思喊。
基本上,模式可以是諸如“鍵盤”次酌,“語音”等的任何文本恨课。 子類型還可以暴露這些的組合。
子類型信息用于IME切換器對話框和措,該對話框可從通知欄和IME設(shè)置中使用庄呈。 該信息還允許框架直接引出IME的特定子類型。 當(dāng)構(gòu)建IME時派阱,使用子類型工具诬留,因為它有助于用戶識別和在不同的IME語言和模式之間切換。
您可以使用元素在輸入法的XML資源文件之一中定義子類型。 以下代碼段定義了一個具有兩個子類型的IME:美國英語語言環(huán)境的鍵盤子類型文兑,法國的法語語言環(huán)境的另一個鍵盤子類型
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="com.example.softkeyboard.Settings"
android:icon="@drawable/ime_icon"
<subtype android:name="@string/display_name_english_keyboard_ime"
android:icon="@drawable/subtype_icon_english_keyboard_ime"
android:imeSubtypeLanguage="en_US"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="somePrivateOption=true"
/>
<subtype android:name="@string/display_name_french_keyboard_ime"
android:icon="@drawable/subtype_icon_french_keyboard_ime"
android:imeSubtypeLanguage="fr_FR"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="foobar=30,someInternalOption=false"
/>
<subtype android:name="@string/display_name_german_keyboard_ime"
...
/>
/>
6.1.從通知欄中選擇TIME子類型
Android系統(tǒng)管理所有IME公開的所有子類型盒刚。 IME子類型被視為它們所屬的IME的模式。 在通知欄中绿贞,用戶可以為當(dāng)前設(shè)置的IME選擇可用的子類型因块,如以下屏幕截圖所示:
6.2.從系統(tǒng)設(shè)置選擇IME子類型
用戶可以在“系統(tǒng)設(shè)置”區(qū)域的“語言和輸入”設(shè)置面板中控制子類型的使用方式。 在 SoftKeyboard 示例應(yīng)用程序中籍铁,文件InputMethodSettingsFragment.java包含一個在IME設(shè)置中實現(xiàn)子類型啟用程序的實現(xiàn)涡上。 有關(guān)如何在IME中支持輸入法子類型的更多信息,請參閱Android SDK中的 SoftKeyboard 示例應(yīng)用程序拒名。
6.3.在IME子類型之間切換
您可以允許用戶通過提供切換鍵(如球形語言圖標(biāo))作為鍵盤的一部分吩愧,在多個IME子類型之間輕松切換。 這樣做大大提高了鍵盤的可用性增显,并可以幫助避免用戶的失望雁佳。 要啟用此類切換,請執(zhí)行以下步驟:
(1). 在輸入法的XML資源文件中聲明 supportsSwitchingToNextInputMethod = “true” 同云。 您的聲明應(yīng)類似于以下代碼段:
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="com.example.softkeyboard.Settings"
android:icon="@drawable/ime_icon"
android:supportsSwitchingToNextInputMethod="true">
(2). 調(diào)用 shouldOfferSwitchingToNextInputMethod() 方法糖权。
(3). 如果方法返回true,則顯示切換鍵炸站。
(4). 當(dāng)用戶點擊切換鍵時星澳,調(diào)用 switchToNextInputMethod(),將false傳遞給第二個參數(shù)武契。 值false表示系統(tǒng)平等對待所有子類型募判,而不管它們屬于什么IME。 指定true要求系統(tǒng)在當(dāng)前IME中循環(huán)遍歷子類型咒唆。
注意:在Android 5.0(API級別21)之前,switchToNextInputMethod()不知道 supportsSwitchingToNextInputMethod 屬性释液。 如果用戶切換到IME而沒有切換鍵全释,他可能會卡在該IME中,無法輕松地切換出來误债。
七浸船、一般IME注意事項
以下是您實現(xiàn)IME時需要考慮的其他事項:
· 為用戶提供一種直接從IME的UI設(shè)置選項的方法。
· 因為設(shè)備上可以安裝多個IME寝蹈,所以提供了用于用戶從輸入法UI直接切換到不同的IME的方式李命。
· 快速啟動IME的UI。根據(jù)需要預(yù)加載或加載任何大型資源箫老,以便用戶在點擊文本字段時看到IME封字。緩存資源和視圖,用于后續(xù)調(diào)用輸入法。
· 相反阔籽,您應(yīng)該在隱藏輸入法窗口后立即釋放大量內(nèi)存分配流妻,以便應(yīng)用程序可以有足夠的內(nèi)存來運行。如果IME處于隱藏狀態(tài)幾秒鐘笆制,請考慮使用延遲消息來釋放資源绅这。
· 請確保用戶可以為與IME關(guān)聯(lián)的語言或區(qū)域設(shè)置輸入盡可能多的字符。請記住在辆,用戶可以在密碼或用戶名中使用標(biāo)點符號证薇,因此您的IME必須提供許多不同的字符,以允許用戶輸入密碼并訪問設(shè)備匆篓。