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

全键盘输入法

2016年08月21日 ⁄ 综合 ⁄ 共 6048字 ⁄ 字号 评论关闭

该项目实现了一个完整的输入法程序,该输入法包含了小写字母软键盘和数字软键盘,会根据EditText控件相应属性值自动切换到小写字母或数字软键盘。

通过小写字母软键盘也可手动切换到数字软键盘和大写字母软键盘。

1.输入法的初始化工作

输入法程序必须有一个服务类,该类必须继承自InputMethodService,该类的配置代码如下:

        <service
            android:name="net.csdn.leigo.input.method.SoftKeyboard"
            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>

在res目录下新建xml/method.xml:

<?xml version="1.0" encoding="UTF-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android" />

输入法服务类的核心方法是onCreateInputView,该方法返回一个View对象,该对象实际上就是软键盘的界面。

package net.csdn.leigo.input.method;

import net.csdn.leigo.input.R;
import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.KeyboardView;
import android.view.View;

public class SoftKeyboard extends InputMethodService {
	private KeyboardView mInputView;

	@Override
	public View onCreateInputView() {
		// 装载软键盘布局文件
		mInputView = (KeyboardView) getLayoutInflater().inflate(R.layout.input,
				null);
		return mInputView;
	}

}

在onCreateInputView方法中通过装载一个布局文件(input.xml)来创建一个View对象,这个布局文件就是软键盘的界面。

<?xml version="1.0" encoding="utf-8"?>
<net.csdn.leigo.input.method.LatinKeyboardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/keyboard"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true" />

上面的代码只定义了一个控件:LatinKeyboardView,该控件用于显示软键盘的界面,

package net.csdn.leigo.input.method;

import android.content.Context;
import android.inputmethodservice.KeyboardView;
import android.util.AttributeSet;

public class LatinKeyboardView extends KeyboardView {

	static final int KEYCODE_OPTIONS = -100;

	public LatinKeyboardView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public LatinKeyboardView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

}

LatinKeyboardView类并没有实际的代码,只是一个继承自KeyboardView的类。KeyboardView是一个拥有标准键盘的类,如果只想显示标准的软键盘,直接从KeyboardView

类继承即可。

2.响应键盘操作

软键盘有两种类型的按键:输入按键(用于输入数字、符号和字母)和功能按键,要想处理这两种按键的动作,输入法服务类需要实现KeyboardView.OnKeyboardActionListener接口。处理按键的方法是onKey,

public void onKey(int primaryCode, int[] keyCodes) {
		if (isWordSeparator(primaryCode)) { // 处理符号键盘
			if (mComposing.length() > 0) {
				commitTyped(getCurrentInputConnection());
			}
			sendKey(primaryCode);
			updateShiftKeyState(getCurrentInputEditorInfo());
		} else if (primaryCode == Keyboard.KEYCODE_DELETE) { // 处理删除按键
			handleBackspace();
		} else if (primaryCode == Keyboard.KEYCODE_SHIFT) {//处理Shift按键
			handleShift();
		} else if (primaryCode == Keyboard.KEYCODE_CANCEL) { //处理Cancel按键
			handleClose();
			return;
		} else if (primaryCode == LatinKeyboardView.KEYCODE_OPTIONS) {
		} else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE
				&& mInputView != null) {
			Keyboard current = mInputView.getKeyboard();
			if (current == mSymbolsKeyboard
					|| current == mSymbolsShiftedKeyboard) {
				current = mQwertyKeyboard;
			} else {
				current = mSymbolsKeyboard;
			}
			mInputView.setKeyboard(current);
			if (current == mSymbolsKeyboard) {
				current.setShifted(false);
			}
		} else {
			handleCharacter(primaryCode, keyCodes);
		}
	}

上面代码中涉及到一些处理功能按键的方法,例如,handleBackspace(处理退格动作),handleShift(处理Shift键),handleClose(用于关闭软键盘)

private void handleBackspace() {
		final int length = mComposing.length();
		if (length > 1) {
			mComposing.delete(length - 1, length);
			getCurrentInputConnection().setComposingText(mComposing, 1);
			updateCandidates();
		} else if (length > 0) {
			mComposing.setLength(0);
			getCurrentInputConnection().commitText("", 0);
			updateCandidates();
		} else {
			keyDownUp(KeyEvent.KEYCODE_DEL);
		}
		updateShiftKeyState(getCurrentInputEditorInfo());
	}

	private void handleShift() {
		if (mInputView == null) {
			return;
		}

		Keyboard currentKeyboard = mInputView.getKeyboard();
		if (mQwertyKeyboard == currentKeyboard) {
			//切换到字母键盘
			checkToggleCapsLock();
			mInputView.setShifted(mCapsLock || !mInputView.isShifted());
		} else if (currentKeyboard == mSymbolsKeyboard) {
			//切换到符号键盘
			mSymbolsKeyboard.setShifted(true);
			mInputView.setKeyboard(mSymbolsShiftedKeyboard);
			mSymbolsShiftedKeyboard.setShifted(true);
		} else if (currentKeyboard == mSymbolsShiftedKeyboard) {
			mSymbolsShiftedKeyboard.setShifted(false);
			mInputView.setKeyboard(mSymbolsKeyboard);
			mSymbolsKeyboard.setShifted(false);
		}
	}

	private void handleCharacter(int primaryCode, int[] keyCodes) {
		if (isInputViewShown()) {
			if (mInputView.isShifted()) {
				primaryCode = Character.toUpperCase(primaryCode);
			}
		}
		if (isAlphabet(primaryCode) && mPredictionOn) {
			mComposing.append((char) primaryCode);
			getCurrentInputConnection().setComposingText(mComposing, 1);
			updateShiftKeyState(getCurrentInputEditorInfo());
			updateCandidates();
		} else {
			getCurrentInputConnection().commitText(
					String.valueOf((char) primaryCode), 1);
		}
	}

	private void handleClose() {
		commitTyped(getCurrentInputConnection());
		requestHideSelf(0);
		//关闭软键盘
		mInputView.closing();
	}

3.根据EditText控件的属性显示不同的软键盘

如果将<EditText>标签的android:inputType属性设为'number",当EditText控件处于焦点时,会显示数字键盘;否则会显示输入字母的键盘。当EditText控件获得焦点时,会调用

输入法服务类的onStartInput方法,在该方法中会根据当前文本输入框的输入条件显示不同的软键盘。

@Override
	public void onStartInput(EditorInfo attribute, boolean restarting) {
		super.onStartInput(attribute, restarting);

		//清空输入缓冲区
		mComposing.setLength(0);
		updateCandidates();

		if (!restarting) {
			//清空Shift状态
			mMetaState = 0;
		}

		mPredictionOn = false;
		mCompletionOn = false;
		mCompletions = null;

		switch (attribute.inputType & EditorInfo.TYPE_MASK_CLASS) {
		case EditorInfo.TYPE_CLASS_NUMBER:
		case EditorInfo.TYPE_CLASS_DATETIME:
			//当文本输入框要求输入数字或日期时,显示数字软键盘
			mCurKeyboard = mSymbolsKeyboard;
			break;

		case EditorInfo.TYPE_CLASS_PHONE:
			//显示符号软键盘
			mCurKeyboard = mSymbolsKeyboard;
			break;

		case EditorInfo.TYPE_CLASS_TEXT:
			//显示输入字母的软键盘
			mCurKeyboard = mQwertyKeyboard;
			mPredictionOn = true;

			int variation = attribute.inputType
					& EditorInfo.TYPE_MASK_VARIATION;
			if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD
					|| variation == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) {
				mPredictionOn = false;
			}

			if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
					|| variation == EditorInfo.TYPE_TEXT_VARIATION_URI
					|| variation == EditorInfo.TYPE_TEXT_VARIATION_FILTER) {
				mPredictionOn = false;
			}

			if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
				mPredictionOn = false;
				mCompletionOn = isFullscreenMode();
			}

			//更新Shift状态
			updateShiftKeyState(attribute);
			break;

		default:
			//对于所有未知类型,显示字母输入键盘
			mCurKeyboard = mQwertyKeyboard;
			updateShiftKeyState(attribute);
		}

		mCurKeyboard.setImeOptions(getResources(), attribute.imeOptions);
	}

抱歉!评论已关闭.