http://www.cnmsdn.com/html/201003/1268842572ID2157.html
這裡面有4個檔案:
LatinKeyboard.java:
這個就是軟鍵盤類了,直接繼承了 Keyboard類來實現一個輸入拉丁文的鍵盤。它還定義了一個內部類,叫做LatinKey,它直接繼承了Key,來定義一個單獨的鍵,它唯一重載的函數是isInside(int x , int y ),用來判斷一個座標是否在該鍵內。它重載為判斷該鍵是否是CANCEL鍵,如果是則把Y座標減少10px,按照他的解釋是用來還原這個可以關掉鍵盤的鍵的目的地區域。
在LatinKeyboard中,重載了一個createKeyFromXml的函數,這是一個回呼函數,他是鍵盤在描繪鍵的時候調用,它是從一個xml資源檔中載入一個鍵,並且放置在(x,y)座標處。它還判斷了該鍵是否是斷行符號鍵,並儲存起來。
這當中還定義了一個函數是:setImeOptions,它是根據編輯框的當前資訊,來為這個鍵盤的斷行符號鍵設定適當的標籤。這個很好理解,就如前面我說過的一樣,輸入框的不同,會產生不同的斷行符號鍵的label或者icon。在這個函數中,有一個技巧是用了一些imeOption的位資訊,比如IME_MASK_ACTION等等。主要是查看的EditorInfo的Action資訊,這裡有:
IME_ACTION_GO:這個是go操作,它將使用者帶入到一個該輸入框的目標的動作。那麼確認鍵將不會有icon,但是有label:GO
IME_ACTION_NEXT:這個是是next操作,它將使用者帶入到該文字框的寫一個輸入框中。比如說編輯短訊息的時候,內容就是收件者手機號碼框的next文字域。它也只是一個NEXT label就行了。
IME_ACTION_SEARCH; 這個是search操作,它的預設動作就是搜尋。比如在URL框中輸入的時候,預設的就是search操作,它提供了一個像放大鏡一樣的icon。
IME- ACTION_SEND:這個是send操作,它的預設動作就是發送當前的內容。比如在短訊息的內容框裡面輸入的時候,後面通常就是一個發送操作。它也是只提供一個Label:SEND
DEFAULT: 預設情況下表示文字框並沒有什麼特殊的要求,所以只需要設定return的icon即可。
至此,這個類就已經完畢了。很簡單一句話,定義一個xml格式的Keyboard的布局,然後吃繼承一個Keyboard類,即可。
LatinKeyboardView.java
這個類是這裡面最簡單的類了。前面定義的keyboard類通常來說就只是一個概念而已,並不能執行個體出來一個UI,所以需要藉助於一個VIEW類來進行繪製。這個類簡單的繼承了KeyboardView類,然後很奇怪的重載了一個方法,就是onLongPress函數,這個函數是在有長時間按鍵事件的時候會調用。它首先判斷這個按鍵是否是CANCELJIAN鍵,如果是的話就給鍵盤發送一個OPTIONS鍵被按下的事件。我的理解好像是屏蔽這個 CANCEL鍵,然後發送了一個未知的代碼的鍵而已。
Candidateview.java
這個類是候選索引鍵的視圖類,它直接繼承於 View類即可。裡面後很多的私人變數,讓人很惆悵。
mService:這個是這個candidateView的宿主類,也就是該view是為什麼IME服務的。
mSuggestions:這個是建議。比如說當我們輸入一些字母之後IME希望根據輸入來進行聯想建議。
mSelectedIndex: 這個是使用者選擇的詞的索引。
mSelectionHighlight:這個是用來描繪選擇地區高亮的一個類。
mTypedWordValid;鍵入的word是否合法正確。
mBgPadding:背景填充地區。
mWordWidth;這個是對於候選詞的每個詞的寬度。
mWordX:這個是每個候選詞的X座標。有了這兩個變數,就能夠在螢幕上準確的繪製出該候選索引鍵。
mColor*:這幾個是定義了各種顏色。
mPaint: 這個是一個繪圖類,後面會用到
mVerticalPadding;垂直填充地區。
mTargetScrollX:目標滾動的橫座標,即要將目標滾動到何處。
mTotalWidth:總的寬度
mGestureDetector:這是聲明一個手勢監測器
然後是各個方法,這個類設計得還是非常合理的。
CandidateView:建構函式,他的參數是context,這個是IME能夠傳遞給它的,應該是系統的上下文。在這個類裡面,主要是對一些變數的初始化工作。首先初始化的是mSelectionHighlight,它本身是一個繪圖類,用 android的預設背景來初始化,然後設定了一下這個繪圖的一些狀態。然後是對整個iew設定背景色,然後初始化各個color值。注意的是,這個地方都是通過系統的資源管理員來進行資源的擷取,而不是顯示的使用。然後初始化了一個手勢檢測器,它的Listener重載了一個方法,就是 onScroll,這個類是手勢檢測器發現有scroll動作的時候觸發。在這個函數裡,主要是進行滑動的判斷,比如首先得到上一次的x座標,加上本次移動的距離,看是否超過了最大寬度,或者是否越過了最小的最左邊。最後目標移動後距離就是sx,然後再將該視圖移動到sx。然後就是設定水平滾動中水平邊是否需要褪色處理,設定這個候選視圖是否需要draw自己,最後設定水平和垂直的捲軸是否需要顯示。
setService是設定宿主IME。
computeHorizontalScrollRange,這個是表示這個VIEW的水平捲動區域,返回的是候選視圖的總體寬度。
onMeasure:重載的view類,它主要是在布局階段被父視圖所調用。比如當父視圖需要根據其子視圖的大小來進行布局時,就需要回調這個函數來看該view的大小。它首先計算自己的期望的寬度,調用 resolveSize來看是否能夠得到50px的寬度;然後是計算想要的高度,這裡的計算我也沒有怎麼看懂:文本的字型大小 + 垂直的填充大小 + ( 高亮地區的上邊 + 下邊的座標 )。後面括弧裡面的我就沒有看懂,這兩個邊的值是座標,這麼加是什麼意思呢。最後需要注意的是,一定要調用setMeasureDimension來對寬和高進行儲存,否則將會有異常出現。
onDraw: 重載它來進行畫圖的動作。它提供了一塊畫布,如果為空白,則直接調用父類來畫。首先需要判斷是否有候選詞,沒有的話就不用繪製。然後需要初始化背景的填充地區,直接view的背景中得到即可。然後就是對於每一個候選詞進行繪製了。對於每一個候選詞,得到其文本,然後計算其快讀,然後再加上兩邊的空隙。然後就是判斷是否選擇了當前詞:觸摸的位置 + 滾動了的位置 如果是在當前詞的左邊到右邊之間,則將高亮地區繪製在畫布上面,高亮地區設定的大小即為當前詞的大小,並且儲存被選詞的索引。最重要的還是需要將文本繪製在這個候選詞的畫布上面,它進行了一個判斷,判斷哪個才是推薦詞。預設情況下是候選詞的第一個詞,但是它判斷第一個詞是否是合法的,如果是,則第一個詞是候選詞,否者第二個詞才是候選粗,然後進行繪製。最後還需要繪製一條線,來分割各個候選詞。上面提到的總共的寬度在所有的詞都繪製出來之後,就能夠得到了。最後面還有一個就是需要判斷目標滾動是否是當前的,不是就需要滾動過去。
crollToTarget:滾到到目的地區域。首選得到當前值,然後加上一個滾動距離,看是否超過了,然後進行調整即可,然後滾動到相應座標。
setSuggestions:設定候選詞。設定之後,就繪製即可。
onTouchEvent:觸摸事件產生時調用。這裡判斷這個時間是什麼:1.向上,則沒動做;2.移動:如果是向左移動就要手動的選擇候選詞;3.如果是向上,也需要手動選擇候選詞。
takeSuggestionAt;選擇在座標x處的詞,這個處理的是使用者輕輕點擊鍵盤,也就是選擇候選詞。
removeHighlight: 去除高亮顯示。
總而言之,這個類是整個IME的候選詞類,目前還沒有徹底的搞懂,需要調試才能搞懂,敬請期待吧。
SoftKeyboard.java:最為重要最為複雜的類,下次分解。