Android下創建一個輸入法

輸入法是一種可以讓用戶輸入文字的控件。Android提供了一套可擴展的輸入法框架,使得應用程序可以讓用戶選擇各種類型的輸入法,比如基于觸屏的鍵盤輸入或者基于語音。當安裝了特定輸入法之后,用戶即可在系統設置中選擇個輸入法,并在接下來的輸入場景中使用該輸入法。不過在任一時刻,只能使用一個輸入法。

為了在安卓系統下創建一個輸入法,需要新建一個包含擴展了InputMethodService類的安卓應用,并創建一個用于設置的activity,用戶可以通過它將設置選項傳給輸入法的service,因此,你還需要為該設置應用定義展現、交互界面,用于顯示和改變輸入法設置。

本指南包含如下內容:

  • IME的生命周期
  • 在應用程序的manifest中聲明IME組件
  • IME API
  • 設計IME UI界面
  • 將文本從輸入法傳遞給所在的應用程序
  • 和IME subtypes配合工作

如果你過去沒有接觸過輸入法,建議先讀這篇介紹性文章《Onscreen Input Methods》。在SDK中有一個輸入法例程SoftKeyboard可供參考。

輸入法的生命周期

下圖描述了輸入法完整的生命周期:

?

圖1:輸入法的生命周期

接下來的章節將描述如何實現輸入法在生命周期中每一個節點的編碼。

在Manifest中聲明輸入法組件

在安卓系統中,輸入法是一個包含IME service的安卓應用程序。必須在該應用程序的manifest文件中聲明service,請求必要的權限,提供能夠匹配action.view.InputMethod 的intent filter,提供定義輸入法特征的metadata。此外,還要提供一個可以用來修改輸入法參數的設置界面,通過系統設置可以啟動該界面。

如下代碼片段定義了一個輸入法service:

<!-- 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>

第一行粗體字聲明需要BIND_INPUT_METHOD權限來對接系統,第二行粗體字創建了一個能夠匹配android.view.InputMethod的intent filter,第三行粗體字定義了輸入法的metadata。

接下來的代碼片段聲明了輸入法的設置activity:

    <!-- 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>

其中的粗體字定義了一個能夠匹配ACTION_MAIN的intent filter,這表明該acitvity是輸入法應用的主入口。

還可以在這里聲明從UI訪問輸入法設置的權限。

輸入法API

在android.inputmethodservice和android.view.inputmethod包中可以找到輸入法相關的class。其中KeyEvent 是處理字符按鍵的重要類。

輸入法的中心環節就是一個service組件,該組件擴展了InputMethodService。除了實現普通的service生命周期以外,該類需要給UI層提供回調函數,用來處理用戶輸入,并且把文本傳遞給輸入焦點。InputMethodService類實現了大部分管理輸入法狀態、界面以及和當前輸入框通信的邏輯。

以下class同樣重要:

BaseInputConnection

定義了從輸入法到接收輸入的應用程序之間的通信通道。使用該類可以獲取光標附近的文本,可以把字符串提交給文本框,還可以向應用程序發送原生的按鍵消息。應用程序應該擴展該類,而不要實現InputConnection。

KeyboardView

該類擴展了View使其能夠展現出一個鍵盤并且相應用戶的輸入事件。可以通過一個XML文件來定義鍵盤布局。

設計輸入法界面

輸入法有兩個主要的可見的界面元素:輸入窗和候選窗。你只需要實現和輸入法相關的界面元素即可。

Input view

輸入窗是指用戶通過按鍵或手寫或手勢直接產生的文本展示區域。當輸入法首次展現時,系統調用onCreateInputView()回調函數。你需要在該方法中創建輸入法界面布局,并將該布局返回給系統。下面的代碼片段實現了onCreateInputView()方法:

    @Overridepublic View onCreateInputView() {MyKeyboardView inputView =(MyKeyboardView) getLayoutInflater().inflate( R.layout.input, null);inputView.setOnKeyboardActionListener(this);
inputView.setKeyboard(mLatinKeyboard);return mInputView;}

在該實例中,MyKeyboardView實現了類KeyboardView,用來自定義一個鍵盤。如果你使用傳統的QWERTY鍵盤,請參見KeyboardView類。

Candidates view

候選窗用來展現輸入法轉換過的供用戶選擇的候選字串,系統將調用onCreateCandidatesView()使輸入法創建并展現出候選窗。你需要實現該方法,返回一套布局來展現候選窗,當不需要展現候選窗時可以返回null。該方法默認就會返回null,因此如果你什么都不做就會什么都不展現。

在SoftKeyboard例程中你可以找到候選窗實現的例子。

輸入法UI設計的考慮

本章講述輸入法中一些特殊的UI設計。

處理不同的屏幕尺寸

輸入法的UI必須能夠處理不同的屏幕尺寸,需要考慮到屏幕的縱深視圖。在非全屏模式下,輸入法必須為應用程序的輸入框和相關上下文留出足夠的空間,因此輸入法不能占用超過一半的屏幕空間。全屏模式下則不存在這些問題。

處理不同的輸入類型

安卓的輸入框允許你給他設定輸入類型,比如文本、數字、URL、email地址或者搜索串。當你實現了一個新的輸入法,你需要探測每一個輸入框的輸入類型,并為之提供匹配的界面。當然,你不需要檢查用戶輸入文字的合法性,這是應用程序的職責。

例如,下面是輸入法為輸入類型為文本和電話號碼的輸入框展現的界面截圖:

?圖2

當某個輸入控件接收到焦點,輸入法將被啟動,系統會調用輸入法的onStartInputView(),并傳進來一個EditorInfo對象,該對象包含輸入類型和其他輸入控件的相關屬性,其中inputType字段用來表示當前輸入控件的輸入類型。

inputType字段是一個整形數據,它是不同的輸入類型按位或出來的結果。可以使用掩碼TYPE_MASK_CLASS來檢測該字段的值,如:

inputType & InputType.TYPE_MASK_CLASS

其結果可能包含如下值:

  • TYPE_CLASS_NUMBER ? ? ?當前輸入控件只接受數字。如前面所述,此時輸入法應該展現出數字鍵盤。
  • TYPE_CLASS_DATETIME ? ?當前輸入控件只接受日期和時間。

  • TYPE_CLASS_PHONE ? ? ? ??當前輸入控件只接受電話號碼。

  • TYPE_CLASS_TEXT ? ? ? ? ? ?當前輸入控件接受所有字符。

在InputType的參考手冊文檔中可以找到這些常量的詳細描述。inputType字段還可以包含其他的文本變種類型,例如:

  • TYPE_TEXT_VARIATION_PASSWORD ? ?表示當前的文本框是用于輸入密碼,此時輸入法應該展現表示密碼的符號而不是實際文字。
  • TYPE_TEXT_VARIATION_URI ? ? ? ? ? ? ? 表明當前文本框是用于輸入URL或者URI字串。

  • TYPE_TEXT_FLAG_AUTO_COMPLETE ? ?表明在當前文本框中輸入文字時,應用程序會使用字典或搜索引擎或其他機制為其內容自動補全。

在測試這些變種的時候要對inputType使用準確地常亮作比較。在InputType的參考手冊文檔中可以找到所有掩碼常量的詳細信息。

注意:在你的輸入法中,當要把字符傳遞給密碼框時,一定要處理正確:在你的輸入窗和候選窗中務必不要顯示密碼串,輸入法也不要在設備中保存用戶密碼。在《安全設計指南》中可以了解到更多安全議題。

把字符串發送給應用程序

當用戶使用輸入法輸入字符時,輸入法有兩種手段可以將文本發送給應用程序:一、向應用程序發送獨立的鍵盤事件;二、編輯輸入框中光標附近的文本。兩種方式都需要使用一個InputConnection實例來傳遞字符串,調用InputMethodService.getCurrentInputConnection()就可以獲得該實例。

編輯光標附近的字符串

當你對輸入窗中已有的字符串展開編輯時,BaseInputConnection下的一些方法非常有用:

  • getTextBeforeCursor() ? ? ?返回一個CharSequence對象,該對象包含光標前指定個數的字符。
  • getTextAfterCursor() ? ? ? ?返回一個CharSequence對象,該對象包含光標后指定個數的字符。

  • deleteSurroundingText() ??刪除光標前后指定個數的字符。

  • commitText() ? ? ? ? ? ? ? ? ?把一個CharSequence對象提交給輸入窗,并設置新的光標位置。

下面的片段顯示了怎樣用“Hello!”替換光標左側的四個字符:

    InputConnection ic = getCurrentInputConnection();ic.deleteSurroundingText(4, 0);ic.commitText("Hello", 1);ic.commitText("!", 1);

在提交之前組織文本串

如果你的輸入法需要做預測或者要通過幾步組織成象形文字,你可以先在輸入框中顯示當前的輸入過程,最后再把組織成的最終字串提交給輸入框,用這個最終字串替換掉之前的過程串。你可以把中間過程串傳遞給setComposingText()函數來展現這個過程。

下面的代碼段用以說明如何展現這個過程:

    InputConnection ic = getCurrentInputConnection();ic.setComposingText("Composi", 1);
...ic.setComposingText("Composin", 1);...ic.commitText("Composing ", 1);

以上代碼的執行效果展現如下:

?圖3:上屏前的寫作串

攔截硬鍵盤事件

盡管輸入法窗口沒有輸入焦點,但它能夠第一個獲得硬鍵盤按鍵消息,并且選擇是否吃掉它還是繼續向下傳遞給應用程序。例如,當方向鍵按下時,你可以在輸入法候選窗上移動焦點候選,并吃掉這個按鍵消息;當退格鍵按下時,你可以取消輸入法窗口彈出的任何輸入窗或候選窗。

覆蓋onKeyDown()和onKeyUp()方法可以攔截硬鍵盤事件。詳情可以參考SoftKeyboard例程。

如果你不想處理該按鍵消息,記得調用父類的super()方法。

創建輸入法的subtype

輸入法可以通過subtype來定義它所支持的多種輸入模式和語言。一個subtype可以包含如下屬性:

  • 一種語言如en_US或fr_FR
  • 一種輸入模式如語音、鍵盤或手寫
  • 其他特殊的輸入風格、形式或屬性,例如10鍵或qwerty布局。

輸入模式可以是任何的鍵盤布局、語音輸入等等形式。一個subtype可以是這些形式的組合。

輸入法可以在自己的選擇面板中讀取subtype信息來切換不同的subtype,通常在系統通知欄和輸入法設置界面中展現該信息。系統框架還可以通過該信息直接創建出一個指定的輸入法subtype。當你構建一個輸入法時,應使用subtype功能,因為他可以幫助用戶區分和切換不同的輸入法語言和模式。

可以再輸入法的XML資源文件中定義subtype,使用<subtype>根元素。下面的片段定義了一款帶有兩個subtype的輸入法:一個是英文鍵盤,另一個是法文鍵盤。

<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".../>
/>

為了保證你的subtype在UI中能正確地標示出來,要使用%s來獲取subtype標簽,這和獲取subtype locale的方法一樣。接下來會用兩個代碼段來示范,其中第一段是輸入法的XML文件相關代碼段:

    <subtypeandroid:label="@string/label_subtype_generic"android:imeSubtypeLocale="en_US"android:icon="@drawable/icon_en_us"android:imeSubtypeMode="keyboard" />

下一段是輸入法的strings.xml文件部分,其中的資源label_subtype_generic定義如下,它會被輸入法的UI界面使用:

<string name="label_subtype_generic">%s</string>

該設置可以使輸入法的subtype的名字按照本地locale設置來顯示。例如在英文locale下顯示”English (United States)”

從系統通知欄中選擇輸入法的subtype

所有輸入法暴露出的subtype會被安卓系統統一管理。一款輸入法的所有subtypes均隸屬于該輸入法。如下所示,用戶可以在系統通知欄中,選擇當前輸入法下任一可用的subtype:

圖4:從通知欄中選擇輸入法subtype

?圖5:在系統設置面板中設置輸入法的subtype

從系統設置中選擇輸入法subtypes

用戶可以在系統的“語言和輸入”設置面板中設置如何使用subtype。在SoftKeybaord例程的文件InputMethodSettingsFragment.java中包含了如何使用subtype的實現代碼,研究該例程可以了解如何在輸入法中支持subtype的更多信息。

?圖6:選擇一個輸入法的語言

在輸入法的subtype中切換

可以提供一些切換關鍵字,讓用戶更容易地在多個輸入法subtype之間切換,這些關鍵字也可以是全局的語言圖標。這樣可以極大提升鍵盤的可用性,解決用戶通電。要想能夠方便的切換,需要完成如下步驟:

1、在輸入法的XML資源文件中聲明supportsSwitchingToNextInputMethos=“true”,如下:

<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、調用shouldOfferSwitchingToNextInputMethod()方法。

3、如果該方法返回true,則顯示切換關鍵字。

4、當用戶選擇了切換關鍵字后,調用switchToNextInputMeshod()方法,并在第二個參數中傳入false。該false告訴系統平等對待所有subtype,不管他們屬于哪個輸入法。如果指定true,則要求系統在當前輸入法內循環切換subtype。

注意:在Android5.0(API level 21)之前,switchToNextInputMethod()還不知道supportsSwithcingToNextInputMethod屬性。如果用戶切換到某個輸入法而沒有切換關鍵字,他將會得到錯誤,而且可能無法輕易地切換出去。

輸入法典型問題考慮

在你實現一款輸入法的時候還有幾件事需要考慮:

  • 從輸入法界面上提供給用戶修改設置的入口。
  • 因為系統里可能安裝了多個輸入法,需要在輸入法界面上提供可以切換到別的輸入法的入口。
  • 要讓輸入法界面盡可能快的切出來,盡可能地預加載或者在后臺加載尺寸較大的資源,以便用戶點擊可輸入文本框后立刻切出輸入法,要給資源或者視圖考慮做緩存,以備后用。
  • 當輸入法界面被隱藏后,應該盡快釋放輸入法所占用的較大塊的內存,以便應用程序總是有足夠的內存可用。如果輸入法被隱藏了一段時間后,考慮使用延遲消息來釋放資源。
  • 要確保用戶可以輸入在當前語言和locale下的盡可能多的字符。切記用戶可能會在密碼或用戶名中使用標點,所以輸入法必須提供盡可能多的字符以滿足用戶輸入的需要。如果某些字符數不出來,會直接導致他可能無法訪問某臺設備。

?

?

?

轉載于:https://www.cnblogs.com/palance/p/5059575.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/257930.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/257930.shtml
英文地址,請注明出處:http://en.pswp.cn/news/257930.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux awk f,linux的awk詳情(上)

一丶awk介紹AWK是一種處理文本文件的語言&#xff0c;是一個強大的文本分析工具&#xff0c;可以報告生成器&#xff0c;格式化文本輸出1.常用語法awk [options] ‘program’ varvalue file…awk [options] -f programfile varvalue file…awk [options] BEGIN{ action;… } pa…

C#的async和await

C# 5.0中引入了async 和 await。這兩個關鍵字可以讓你更方便的寫出異步代碼。 看個例子&#xff1a; public class MyClass {public MyClass(){DisplayValue(); //這里不會阻塞System.Diagnostics.Debug.WriteLine("MyClass() End.");}public Task<double> Get…

eclipse創建android工程,在eclipse創建android 工程

1.在工具欄選擇"New".在彈出對話框里&#xff0c;開打android文件夾&#xff0c;選擇"android application Project"&#xff0c;選擇“Next”.2.Application Name: 應用程序名稱。Projetc Name: 工程名稱。Packet Name: 包名稱. 注意&#xff0c;包名稱…

SQL select查詢原理--查詢語句執行原則轉

1.單表查詢&#xff1a;根據WHERE條件過濾表中的記錄&#xff0c;形成中間表&#xff08;這個中間表對用戶是不可見的&#xff09;&#xff1b;然后根據SELECT的選擇列選擇相應的列進行返回最終結果。 1)簡單的單表查詢 SELECT 字段 FROM 表名 WHERE 條件表達式 那它們是按什么…

android導航二級分類,Android實現騰訊新聞的新聞類別導航效果

效果圖如下所示&#xff1a;1、在Adapter中加入如下代碼private int clickTemp -1;//TODO 被選擇的item下標/** * TODO 傳入下標&#xff0c;設置被選擇的item * * param position */public void setSelection(int position) {clickTemp position;}2、在Adapter的getView方法…

Linux下訪問window掛載的磁盤

點擊window掛在的磁盤,如下圖左側"文檔". 出現如下錯誤: Error mounting /dev/sda3 .... Command-line mount -t "ntfs" -o "uhelperudisks2 修復辦法: sudo ntfsfix /dev/sda6 參考資料: 1. win8安裝ubuntu后不能訪問windows其他磁盤轉載于:https:…

linux遍歷目錄源代碼

<pre code_snippet_id"1622396" snippet_file_name"blog_20160324_1_744516" name"code" class"cpp">遍歷目錄獲取整個目錄的占用空間: uint64_t dir_space(char *path) {int ret 0;uint64_t space 0;char cur_dir[PATH_MAX …

android studio 手動安裝gradle,Android Studio 如何安裝Gradle?

今天新下載安裝了Android Studio 2.1&#xff0c;啟動并新建第一個項目&#xff0c;結果卡在 gradle 上。網上搜原因&#xff0c;得到這個網頁&#xff1a;http://blog.csdn.net/maxsky/article/details/50204093。說是要自己下載 gradle的壓縮包&#xff0c;查了項目目錄下的 …

Label 表達式綁定

Text<%#"總金額為: "Convert.ToString(Convert.ToDecimal(TextBox1.Text)*Convert.ToInt32(TextBox2.Text)%> Page_Load { Page.DataBind(); }轉載于:https://www.cnblogs.com/handsomer/p/4150386.html

(轉)如果知道dll文件是面向32位系統還是面向64位系統的?

本文為轉載文章&#xff0c;原文地址&#xff1a;http://www.cnblogs.com/qguohog/archive/2011/09/13/2174897.html&#xff0c;僅僅是記錄供后續使用&#xff0c;如有侵權請通知刪除。 在發布dll時&#xff0c;可以選擇編譯為x86模式、x64模式以及Any Cpu模式等。那么對于已經…

Spring Roo 簡介

一直以來&#xff0c;Java/Spring開發被認為是笨重的代表&#xff0c;無法快速生成項目原型和骨架。所以&#xff0c;Spring推出了Spring Roo這個項目&#xff0c;幫助我們快速生成項目原型。本文參考自Spring Roo的官方文檔&#xff0c;如果熟悉英文的話可以直接看原文檔&…

雙緩沖 android,Android 的 SurfaceView 雙緩沖應用

075 int index 0;本文引用地址&#xff1a;http://www.eepw.com.cn/article/201610/305442.htm076 try {077 index field.getInt(R.drawable.class);078 } catch (IllegalArgumentException e) {079 // TODO Auto-generated catch block080 e.printStackTrace();081 } catch …

Windows—JDK安裝與環境變量配置

本文介紹JDK的安裝與環境變量配置。 工具/原料 JDK1.8.0_65WIN7 32bitjdk-8u65-windows-i586.exe方法/步驟 安裝JDK 選擇安裝目錄 安裝過程中會出現兩次 安裝提示 。第一次是安裝 jdk &#xff0c;第二次是安裝 jre 。建議兩個都安裝在同一個java文件夾中的不同文件夾中。&…

典型案例道出“服務臺”的價值

引 言&#xff1a;作為運營管理著龐大IT系統的CIO&#xff0c;相信您或多或少都嘗試過&#xff0c;或正建有IT服務臺&#xff08;或幫助臺&#xff09;&#xff0c;然而您可能依然面臨服務效率低下&#xff0c;用戶滿意度欠佳的 困擾。這其中的原因&#xff0c;多半就在于您的服…

數據的藝術

數據的藝術概念:數據 --程序操作的對象&#xff0c;用于描述客觀事物。數據的特點:a. 可以輸入到計算機b. 可以被計算機程序處理*數據是一個抽象的概念&#xff0c;將其進行分類得到程序設計語言中的類型。數據元素 -組成數據的基本單位a. 數據項:一個數據元素由若干數據項組成…

處理ajax的session超時

做web開發時&#xff0c;當session超時時&#xff0c;如果不是ajax請求&#xff0c;很簡單就能實現跳到指定的頁面。但是ajax請求就會有問題。session超時的時候&#xff0c;點擊到ajax請求就會彈出一些頁面源碼文件。 首先建了個攔截器&#xff0c;來判斷session超時。用戶登錄…

菜根譚#249

色欲火熾&#xff0c;而一念及病時便興似寒灰&#xff1b; 名利飴甘&#xff0c;而一想到死地便味如嚼蠟。 故人常憂死慮病&#xff0c;亦可消幻業而長道心。轉載于:https://www.cnblogs.com/star4knight/p/4154590.html

實現物聯網項目,你需要提前知道的6件事情

目前為止&#xff0c;對于大多數尋求數字化與服務化轉型的制造商來說&#xff0c;實現物聯網應用項目仍然是一個很大的挑戰。 我們此前做過一項研究&#xff0c;到2016年底,全球企業級物聯網項目將超過10000個。但是其中大部分的項目都還是處于初期概念驗證(PoC)階段&#xff0…

android腳本快捷方式,Android:如何創建主屏幕快捷方式啟動shell腳本?

答案&#xff1a;您的問題的答案應該是GScript(開放源代碼和“根除設備上的任何地方”),但是當腳本完成時,誰想要盯著該模態終端輸出屏幕&#xff1f;詳情如下.> SManager (free version)將讓您將自定義腳本存儲在設備的任何位置,即使您使用根設備的內部存儲也是如此.它將允…

讀書 文摘 筆記

鳳凰項目: 一個IT運維的傳奇故事 微信商城開發實戰 跨境電商多平臺運營 活出生命的意義 托馬斯阿爾瓦愛迪生 奇跡的一生 阿爾伯特愛因斯坦 固執 自信 專利局 我的世界觀 愛因斯坦 艾薩克牛頓 母親讓牛頓停學在家務農&#xff0c;贍養家庭。但牛頓一有機會便埋首書卷&#…