編輯:Android編程入門
上一篇介紹了完成Android輸入法的最小化步驟,它只能將按鍵對應的字符上屏。一般的東亞語言都有一個轉換的過程,比如漢語輸入拼音,需要由拼音轉成漢字再上屏。本文將在前文基礎上加入完成轉換過程所必需的候選窗。本文代碼可參見https://github.com/palanceli/AndroidXXIME/tree/v2。
如下圖所示,用紅框框出來的窗體是候選窗,其內的字符創叫做候選串,點擊候選窗使之進入輸入控件叫做上屏。沒有輸入的時候隱藏候選窗,當輸入字串還未上屏時顯示候選窗:

引入候選窗需要完成兩個步驟:
一、創建CandidateView,該窗口需要覆蓋如下兩個方法,已完成自繪:
二、覆蓋AndroidXXIME類的如下兩個方法:
在該方法中創建CandidateView。
在該方法中響應按鍵消息,如:當按下字母鍵,則展現候選窗以及候選字串;當按下空格,則上屏候選字串,等等。
public CandidateView(Context context) {
super(context);
Log.d(this.getClass().toString(), "CandidateView: ");
// 設置前景、背景色、字體、字號
Resources r = context.getResources();
setBackgroundColor(getResources().getColor(R.color.candidate_background, null));
mColorNormal = r.getColor(R.color.candidate_normal, null);
mVerticalPadding = r.getDimensionPixelSize(R.dimen.candidate_vertical_padding);
mPaint = new Paint();
mPaint.setColor(mColorNormal);
mPaint.setAntiAlias(true);
mPaint.setTextSize(r.getDimensionPixelSize(R.dimen.candidate_font_height));
mPaint.setStrokeWidth(0);
setWillNotDraw(false); // 覆蓋了onDraw函數應清除該標記
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.d(this.getClass().toString(), "onMeasure: ");
int wMode = MeasureSpec.getMode(widthMeasureSpec);
int wSize = MeasureSpec.getSize(widthMeasureSpec);
int measuredWidth = resolveSize(50, widthMeasureSpec);
final int desiredHeight = ((int)mPaint.getTextSize()) + mVerticalPadding;
// 系統會根據返回值確定窗體的大小
setMeasuredDimension(measuredWidth, resolveSize(desiredHeight, heightMeasureSpec));
}
@Override
protected void onDraw(Canvas canvas) {
Log.d(this.getClass().toString(), "onDraw: ");
super.onDraw(canvas);
if (mSuggestions == null)
return;
// 依次繪制每組候選字串
int x = 0;
final int count = mSuggestions.size();
final int height = getHeight();
final int y = (int) (((height - mPaint.getTextSize()) / 2) - mPaint.ascent());
for (int i = 0; i < count; i++) {
String suggestion = mSuggestions.get(i);
float textWidth = mPaint.measureText(suggestion);
final int wordWidth = (int) textWidth + X_GAP * 2;
canvas.drawText(suggestion, x + X_GAP, y, mPaint);
x += wordWidth;
}
}
public void setSuggestions(List<String> suggestions) {
// 設置候選字串列表
if (suggestions != null) {
mSuggestions = new ArrayList<String>(suggestions);
}
invalidate();
requestLayout();
}
}
該方法會在每次輸入法被呼出的時候調用,如函數名所示,在這裡創建候選窗口。
public class AndroidXXIME extends InputMethodService
implements KeyboardView.OnKeyboardActionListener {
……
@Override public View onCreateCandidatesView(){
Log.d(this.getClass().toString(), "onCreateCandidatesView: ");
candidateView = new CandidateView(this);
return candidateView;
}
……
}
public class AndroidXXIME extends InputMethodService
implements KeyboardView.OnKeyboardActionListener {
……
@Override
public void onKey(int primaryCode, int[] keyCodes) {
InputConnection ic = getCurrentInputConnection();
playClick(primaryCode);
switch(primaryCode){
case Keyboard.KEYCODE_DELETE :
// 如果收到的是DELETE鍵,則刪除光標前的一個字符
ic.deleteSurroundingText(1, 0);
break;
case Keyboard.KEYCODE_DONE:
// 如果收到的是DONE鍵,則執行回車
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
break;
default:
char code = (char)primaryCode;
if(code == ' '){ // 如果收到的是空格
if(m_composeString.length() > 0) { // 如果有寫作串,則將首個候選提交上屏
ic.commitText(m_composeString, m_composeString.length());
m_composeString.setLength(0);
}else{ // 如果沒有寫作串,則直接將空格上屏
ic.commitText(" ", 1);
}
}else { // 否則,將字符計入寫作串
m_composeString.append(code);
ic.setComposingText(m_composeString, 1);
}
updateCandidates();
}
}
}
在updateCandidates()函數中向CandidateView塞入候選字串列表,並觸發該窗口更新。
當在系統“語言和輸入法”-“更改鍵盤”中選擇輸入法時,

系統會調用該輸入法InputMethodService的如下方法:
當一個輸入控件獲得焦點,呼出輸入法,到它失去焦點,這期間成為一次會話。當一個會話開始時,系統會調用輸入法InputMethodService的如下方法:
完成以上步驟之後,輸入法就多出了候選窗口,下圖中淺藍色窗體既是:

在處理上還是很簡陋,比如退格還不支持刪除輸入串,還不支持點擊上屏,等等。這些屬於業務邏輯的細節了,可以慢慢精耕細作。
Android課程---關於GridView網格視圖的學習
activity_ui6.xml<?xml version=1.0 encoding=utf-8?><GridView xmlns:android=ht
Mac下載安裝Android Studio教程
今天把公司閒置的一台Mac-mini重裝了下系統感覺用著速度還不錯,平時上班用的機器USB有些問題,所以打算用這台Mac。以往開發用Intellij Idea就夠用,但是
Anfroid 在界面中顯示圖片 ImageView
ImageView1.什麼是ImageView是顯示圖片的一個控件2.ImageView屬性android:src ImageView的內容顏色 an
Android Studio ADB響應失敗解決方法
當啟動Android Studio時,如果彈出adb not responding. you can wait more,or kill adb.exe pro