如图:
该项目总共20个目标文件!~
AbstractIME是抽象类,实现对输入方法的管理!~定义如下:
public abstract class AbstractIME extends InputMethodService implements
KeyboardView.OnKeyboardActionListener,
CandidateView.CandidateViewListener
InputMethodService为android输入方式服务!~
CandidatesContainer是实现向前或向后移动以及翻转等操作!~
CandidateView是视图显示候选字!
CangjieDictionary 是词典!
Editor是编辑和处理显示!
CangjieIME继承AbstractIME,实现对输入方法的管理!~
CangjieTable是字母和计算指数的定义!
DictionaryLoader是线程类,实现对词典的加载!
ImePreferenceActivity是输入法的主要界面!
KeyboardSwitch是软键盘的切换!(中英切换)
PhraseDictionary是读短语字典以及提供参考字符!
SoftKeyboard继承Keyboard,实现对软键盘的管理!
SoftKeyboardView显示软键盘键,渲染和检测按键。
SoundMotionEffect是对应键盘的声音提示!
WordDictionary是词典!
ZhuyinDictionary继承WordDictionary实现对词典中读取字!
ZhuyinEditor继承Editor实现编辑框!
ZhuyinIME继承AbstractIME,实现对输入方法的管理!~
ZhuyinTable实现笔画显示!
程序定义了两个输入法服务,定义如下:
主要的操作是在AbstractIME类中
//抽象类
public abstract class AbstractIME extends InputMethodService implements
KeyboardView.OnKeyboardActionListener,
CandidateView.CandidateViewListener
{
//显示软键盘,使按键和按键检测
protected SoftKeyboardView inputView;
//包含所有候选人页面,用户可以向前移动(见下页)或向后移动(上一)页,这些候选人中选择一个。
private CandidatesContainer candidatesContainer;
//软盘切换
private KeyboardSwitch keyboardSwitch;
//编辑框
private Editor editor;
//词典
private WordDictionary wordDictionary;
//推荐词
private PhraseDictionary phraseDictionary;
//对应键的声音
private SoundMotionEffect effect;
private int orientation;
protected abstract KeyboardSwitch createKeyboardSwitch(Context context);
protected abstract Editor createEditor();
protected abstract WordDictionary createWordDictionary(Context context);
@Override
public void onCreate()
{
super.onCreate();
//初始化
keyboardSwitch = createKeyboardSwitch(this);
editor = createEditor();
wordDictionary = createWordDictionary(this);
phraseDictionary = new PhraseDictionary(this);
effect = new SoundMotionEffect(this);
orientation = getResources().getConfiguration().orientation;
// Use the following line to debug IME service.
// android.os.Debug.waitForDebugger();
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
if (orientation != newConfig.orientation)
{
// Clear composing text and candidates for orientation change.
escape();
orientation = newConfig.orientation;
}
super.onConfigurationChanged(newConfig);
}
//更新节点
@Override
public void onUpdateSelection(int oldSelStart, int oldSelEnd,
int newSelStart, int newSelEnd, int candidatesStart,
int candidatesEnd)
{
super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd,
candidatesStart, candidatesEnd);
if ((candidatesEnd != -1)
&& ((newSelStart != candidatesEnd) || (newSelEnd != candidatesEnd)))
{
// Clear composing text and its candidates for cursor movement.
escape();
}
// Update the caps-lock status for the current cursor position.
updateCursorCapsToInputView();
}
//插入
@Override
public void onComputeInsets(InputMethodService.Insets outInsets)
{
super.onComputeInsets(outInsets);
outInsets.contentTopInsets = outInsets.visibleTopInsets;
}
@Override
public View onCreateInputView()
{
inputView = (SoftKeyboardView) getLayoutInflater().inflate(
R.layout.input, null);
inputView.setOnKeyboardActionListener(this);
return inputView;
}
@Override
public View onCreateCandidatesView()
{
candidatesContainer = (CandidatesContainer) getLayoutInflater()
.inflate(R.layout.candidates, null);
candidatesContainer.setCandidateViewListener(this);
return candidatesContainer;
}
//开始
@Override
public void onStartInputView(EditorInfo attribute, boolean restarting)
{
super.onStartInputView(attribute, restarting);
// Reset editor and candidates when the input-view is just being
// started.
editor.start(attribute.inputType);
clearCandidates();
effect.reset();
keyboardSwitch.initializeKeyboard(getMaxWidth());
// Select a keyboard based on the input type of the editing field.
keyboardSwitch.onStartInput(attribute.inputType);
bindKeyboardToInputView();
}
//完成输入
@Override
public void onFinishInput()
{
// Clear composing as any active composing text will be finished, same
// as in
// onFinishInputView, onFinishCandidatesView, and onUnbindInput.
editor.clearComposingText(getCurrentInputConnection());
super.onFinishInput();
}
//完成输入
@Override
public void onFinishInputView(boolean finishingInput)
{
editor.clearComposingText(getCurrentInputConnection());
super.onFinishInputView(finishingInput);
// Dismiss any pop-ups when the input-view is being finished and hidden.
inputView.closing();
}
//候选词取完毕
@Override
public void onFinishCandidatesView(boolean finishingInput)
{
editor.clearComposingText(getCurrentInputConnection());
super.onFinishCandidatesView(finishingInput);
}
@Override
public void onUnbindInput()
{
editor.clearComposingText(getCurrentInputConnection());
super.onUnbindInput();
}
//绑定
private void bindKeyboardToInputView()
{
if (inputView != null)
{
// Bind the selected keyboard to the input view.
inputView.setKeyboard(keyboardSwitch.getCurrentKeyboard());
updateCursorCapsToInputView();
}
}
//更新
private void updateCursorCapsToInputView()
{
InputConnection ic = getCurrentInputConnection();
if ((ic != null) && (inputView != null))
{
int caps = 0;
EditorInfo ei = getCurrentInputEditorInfo();
if ((ei != null) && (ei.inputType != EditorInfo.TYPE_NULL))
{
caps = ic.getCursorCapsMode(ei.inputType);
}
inputView.updateCursorCaps(caps);
}
}
//提交
private void commitText(CharSequence text)
{
if (editor.commitText(getCurrentInputConnection(), text))
{
// Clear candidates after committing any text.
clearCandidates();
}
}
//按键
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK) && (event.getRepeatCount() == 0))
{
// Handle the back-key to close the pop-up keyboards.
if ((inputView != null) && inputView.handleBack())
{
return true;
}
}
return super.onKeyDown(keyCode, event);
}
public void onKey(int primaryCode, int[] keyCodes)
{
if (keyboardSwitch.onKey(primaryCode))
{
escape();
bindKeyboardToInputView();
return;
}
if (handleOption(primaryCode) || handleCapsLock(primaryCode)
|| handleEnter(primaryCode) || handleSpace(primaryCode)
|| handleDelete(primaryCode) || handleComposing(primaryCode))
{
return;
}
handleKey(primaryCode);
}
public void onText(CharSequence text)
{
commitText(text);
}
public void onPress(int primaryCode)
{
effect.vibrate();
effect.playSound();
}
public void onRelease(int primaryCode)
{
// no-op
}
public void swipeLeft()
{
// no-op
}
public void swipeRight()
{
// no-op
}
public void swipeUp()
{
// no-op
}
public void swipeDown()
{
requestHideSelf(0);
}
public void onPickCandidate(String candidate)
{
// Commit the picked candidate and suggest its following words.
commitText(candidate);
setCandidates(phraseDictionary.getFollowingWords(candidate.charAt(0)),
false);
}
private void clearCandidates()
{
setCandidates("", false);
}
private void setCandidates(String words, boolean highlightDefault)
{
if (candidatesContainer != null)
{
candidatesContainer.setCandidates(words, highlightDefault);
setCandidatesViewShown((words.length() > 0)
|| editor.hasComposingText());
if (inputView != null)
{
inputView.setEscape(candidatesContainer.isShown());
}
}
}
private boolean handleOption(int keyCode)
{
if (keyCode == SoftKeyboard.KEYCODE_OPTIONS)
{
// TODO: Do voice input here.
return true;
}
return false;
}
private boolean handleCapsLock(int keyCode)
{
return (keyCode == Keyboard.KEYCODE_SHIFT)
&& inputView.toggleCapsLock();
}
private boolean handleEnter(int keyCode)
{
if (keyCode == '\n')
{
if (inputView.hasEscape())
{
escape();
} else if (editor.treatEnterAsLinkBreak())
{
commitText("\n");
} else
{
sendKeyChar('\n');
}
return true;
}
return false;
}
private boolean handleSpace(int keyCode)
{
if (keyCode == ' ')
{
if ((candidatesContainer != null) && candidatesContainer.isShown())
{
// The space key could either pick the highlighted candidate or
// escape
// if there's no highlighted candidate and no composing-text.
if (!candidatesContainer.pickHighlighted()
&& !editor.hasComposingText())
{
escape();
}
} else
{
commitText(" ");
}
return true;
}
return false;
}
private boolean handleDelete(int keyCode)
{
// Handle delete-key only when no composing text.
if ((keyCode == Keyboard.KEYCODE_DELETE) && !editor.hasComposingText())
{
if (inputView.hasEscape())
{
escape();
} else
{
sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
}
return true;
}
return false;
}
private boolean handleComposing(int keyCode)
{
if (editor.compose(getCurrentInputConnection(), keyCode))
{
// Set the candidates for the updated composing-text and provide
// default
// highlight for the word candidates.
setCandidates(wordDictionary.getWords(editor.composingText()), true);
return true;
}
return false;
}
/**
* Handles input of SoftKeybaord key code that has not been consumed by
* other handling-methods.
*/
private void handleKey(int keyCode)
{
if (isInputViewShown() && inputView.isShifted())
{
keyCode = Character.toUpperCase(keyCode);
}
commitText(String.valueOf((char) keyCode));
}
/**
* Simulates PC Esc-key function by clearing all composing-text or
* candidates.
*/
protected void escape()
{
editor.clearComposingText(getCurrentInputConnection());
clearCandidates();
}
}
代码不多,适合学习!
学习的目标是成熟!~~~~