现在的位置: 首页 > 综合 > 正文

开源项目之Android繁体中文输入法

2013年09月11日 ⁄ 综合 ⁄ 共 8990字 ⁄ 字号 评论关闭

一款功能强大的输入法,集合 “广东话、拼音、仓颉、速成”四种常用中文输入法,以及英文、数字及符号键盘,一按独立切换键即可变更。同一键盘可作中英文输入,无需切换,支持联想字功能,融合英汉字典。
  繁体中文输入工具是一款功能强大的输入法,集合 "广东话、拼音、仓颉、速成"四种常用中文输入法,以及英文、数字及符号键盘,一按独立切换键即可变更。同一键盘可作中英文输入,无需切换,支持联想字功能,融合英汉字典。
Android 繁体中文输入法基于 Android 输入法框架开发,代码力求小巧可读。

如图:

该项目总共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实现笔画显示!

程序定义了两个输入法服务,定义如下:

        <service
            android:name="ZhuyinIME"
            android:label="@string/zhuyin_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>
        <service
            android:name="CangjieIME"
            android:label="@string/cangjie_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>

主要的操作是在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();
	}
}


代码不多,适合学习!

学习的目标是成熟!~~~~


抱歉!评论已关闭.