來源:http://www.oschina.net/question/12_1559
學習目標:
- 實現新的輸入法
學習目的:
- 掌握Android輸入法框架
學習收獲:
Android 1.5 新特色之一就是輸入法框架(Input Method Framework,IMF),正是它的出現,才為誕生不帶實體鍵盤的設備提供了可能。IMF設計用來支持不同的IME,包括了soft keyboard,hand-writing recognizes和hard keyboard translators。這里,我們把焦點鎖定在soft keyboard上。
新特色對普通應用開發者而言,應該確保讓應用能夠和IMF很好的配合,提供優秀的用戶體驗。應用要做的最重要事情,就是對每個EditText使用 新的屬性android:inputType,這個屬性實際代替了很多已經存在的屬性,包括android:password, android:singleLine, android:numeric, android:phoneNumber, android:capitalize, android:autoText, android:editable。如果你兩個都聲明了,Cupcake設備就會使用新的android:inputType屬性,而忽視其他的。
主要的API就是android.view.inputmethod.InputMethodManager,你可以通過Context.getSystemService方法來獲取。它允許你和全局輸入法狀態進行交互,例如顯式隱藏或者顯示IME的輸入法區域。
新特色對於系統開發人員而言,其提供了開發各種各樣語言輸入法的實現入口,有了它,其他語言輸入法才能進駐Android。以下內容即關注如何實現一個輸入法。
要創建一個輸入法,需要繼承android.inputmethodservice.InputMethodService。這個類提供了輸入法的 基本實現,包括狀態管理、控制輸入法可見,還有和當前activity通訊。Android提供了兩個輸入法和一個示例,這兩個輸入法分別是 PinyinIME和LatinIME輸入法,你可以在源碼packages/inputmethods下找到,示例即SoftKeyboard,可以在 SDK 1.5下的platforms/android-1.5/samples下找到。這三個輸入法提供了目前實現Android平台輸入法實現的最佳參考。
輸入法的打包方式和其他應用是相同的,在AndroidManifest.xml中,要把輸入法聲明為service,並附帶上合適的intent filter和相關的meta data。如下所示:
<service android:name=".DemoIme" android:label="@string/ime_name" 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>
如果輸入法允許用戶調整設置,那么你還應該提供一個setting activity。這個時候不要忘記在input-method的XML文件中,加入相關的屬性,如以下所示(這個文件就是剛才meta-data中的@xml/method):
<input-method xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="com.demo.SettingsActivity" android:isDefault="@bool/im_is_default" />
輸入法在UI展現上,有兩個主要的可見元素,input view和candiate view。但這不是必需的,可以根據實際需要選擇你需要的元素。Input View,是用戶從鍵盤、手寫或者其他方式輸入文本的地方。當輸入法第一次展現的時 候,InputMethodService.onCreateInputView()就會被調用。Candidates View,是候選詞匯集合出現的地方。其可有可無,可以在調用InputMethodService.onCreateCandidatesView時返 回null,–這是它的默認行為。
應用的文本區可以有不同的輸入類型,包括文本、數值、URL、郵箱地址和搜索,因此在你實現新的輸入法時,需要當心不同的輸入類型。輸入法並不會自 動切換不同的輸入類型,所以你要在IME中支持所有的類型。不過可以輕松一點的是, IME並不負責輸入內容的校驗,—因為這是應用的職責。
InputMethodService.onStartInputView()被調用時,會傳入一個EditorInfo對象,這個對象包含了關於 輸入類型和text field的其他屬性的細節。EditorInfo.inputType和EditorInfo.TYPE_CLASS_MASK可以是很多值,包括 TYPE_CLASS_NUMBER、TYPE_CLASS_DATETIME、TYPE_CLASS_PHONE、TYPE_CLASS_TEXT。可以通過android.text.InputType了解更多信息。
要把文本發送給應用有兩種方式,你可以發送單一的按鍵事件,也可以在應用的文本框內編輯光標附近的文本。發送按鍵事件,可以簡單構造 KeyEvent對象,並且調用InputConnection.sendKeyEvent(),或者更加方便一點,使用 InputMethodService.sendDownUpKeyEvents(keyEventCode)。在編輯文本框 時,android.view.inputmethod.InputConnection有一些很有用的方法,例如 getTextBeforeCursor()等等。