Java 自定义键盘:处理输入类型更改
我遇到了一个我无法解决的问题。我根据示例编写了一个简单的自定义输入法键盘 它基本上有两个自定义键盘,一个用于字母,一个用于数字。它们使用不同的布局 但是,当我添加两个Java 自定义键盘:处理输入类型更改,java,android,android-layout,android-edittext,android-softkeyboard,Java,Android,Android Layout,Android Edittext,Android Softkeyboard,我遇到了一个我无法解决的问题。我根据示例编写了一个简单的自定义输入法键盘 它基本上有两个自定义键盘,一个用于字母,一个用于数字。它们使用不同的布局 但是,当我添加两个EditText控件时,一个用于文本,另一个用于数字,键盘不会刷新为它所属的类型。我的意思是,如果我先用inputType=“text”选择EditText,就会出现QWERTY键盘布局。但是,当我用inputType=“number”选择第二个EditText时,QWERTY键盘再次出现。但是,它应该为连接到代码中的数字加载不同的
EditText
控件时,一个用于文本,另一个用于数字,键盘不会刷新为它所属的类型。我的意思是,如果我先用inputType=“text”
选择EditText
,就会出现QWERTY键盘布局。但是,当我用inputType=“number”
选择第二个EditText
时,QWERTY键盘再次出现。但是,它应该为连接到代码中的数字加载不同的布局
换句话说,这里是测试活动布局:
现在,如果我选择“文本”字段,QWERTY键盘显示如下:
但是,如果我选择“数字”字段,QWERTY键盘仍然会显示错误
预期的行为是显示此键盘
这是CustomIME的代码,我尝试在视图上使用postInvalidate()
,在onInitializeInterface()期间预加载所有布局,但没有任何效果。它永远不会正确地切换到号码的布局
public class CustomIME extends InputMethodService
implements KeyboardView.OnKeyboardActionListener {
public static final String CUSTOM_IME = "CUSTOM_IME";
private KeyboardView mKeyboardView;
private Keyboard mKeyboardCurrent;
private KeyboardType mKeyboardTypeCurrent = KeyboardType.QWERTY_LETTERS;
private boolean mCAPs = false;
enum KeyboardType {
QWERTY_LETTERS,
NUMBERS
}
@Override
public View onCreateInputView() {
loadCurrentKeyboard();
mKeyboardView = (KeyboardView) getLayoutInflater().inflate(R.layout.custom_ime_keyboard, null);
mKeyboardView.setBackgroundResource(R.drawable.btn_gradient);
mKeyboardView.setOnKeyboardActionListener(this);
if (mKeyboardCurrent != null) {
mKeyboardView.setKeyboard(mKeyboardCurrent);
}
return mKeyboardView;
}
@Override
public void onInitializeInterface() {
// tried loading everything here but did not make a difference
}
private void loadCurrentKeyboard() {
if (mKeyboardTypeCurrent == KeyboardType.QWERTY_LETTERS) {
mKeyboardCurrent = new Keyboard(getApplicationContext(), R.xml.custom_ime_qwerty);
} else if (mKeyboardTypeCurrent == KeyboardType.NUMBERS) {
mKeyboardCurrent = new Keyboard(getApplicationContext(), R.xml.custom_ime_number);
} else {
Log.e(CUSTOM_IME, "Invalid keyboard type");
}
}
@Override
public void onStartInput(EditorInfo attribute, boolean restarting) {
super.onStartInput(attribute, restarting);
switch (attribute.inputType & InputType.TYPE_MASK_CLASS) {
case InputType.TYPE_CLASS_NUMBER:
boolean signed = (attribute.inputType & InputType.TYPE_NUMBER_FLAG_SIGNED) != 0;
boolean decimal = (attribute.inputType & InputType.TYPE_NUMBER_FLAG_DECIMAL) != 0;
// set default
mKeyboardTypeCurrent = KeyboardType.QWERTY_LETTERS;
if (!signed && !decimal) {
mKeyboardTypeCurrent = KeyboardType.NUMBERS;
}
break;
case InputType.TYPE_CLASS_TEXT:
default:
mKeyboardTypeCurrent = KeyboardType.QWERTY_LETTERS;
}
// This did not make a difference
if (mKeyboardView != null) {
mKeyboardView.postInvalidate();
}
}
@Override
public void onKey(int primaryCode, int[] keyCodes) {
InputConnection inputConnection = getCurrentInputConnection();
switch (primaryCode) {
default:
char asciiCode = (char) primaryCode;
if (Character.isLetter(asciiCode) && mCAPs) {
asciiCode = Character.toUpperCase(asciiCode);
}
inputConnection.commitText(String.valueOf(asciiCode), 1);
}
}
}
以及布局:
自定义\u ime\u keyboard.xml:
<?xml version="1.0" encoding="UTF-8"?>
<android.inputmethodservice.KeyboardView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/custom_ime_keyboard_id1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:keyPreviewLayout="@layout/custom_ime_preview" />
活动\u main.xml
<LinearLayout
android:id="@+id/layout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_margin="10dp"
android:orientation="horizontal">
<EditText
android:id="@+id/edit1"
android:layout_width="100dp"
android:layout_height="60dp"
android:inputType="text"
android:hint="Text"
android:padding="10dp"
android:textSize="12sp" />
<EditText
android:id="@+id/edit2"
android:layout_width="100dp"
android:layout_height="60dp"
android:hint="Number"
android:inputType="number"
android:padding="10dp"
android:textSize="12sp" />
</LinearLayout>
最后是键盘布局(custom\u ime\u qwerty.xml,以及custom\u ime\u number.xml)
等
我认为这是您需要获得的回调:
在显示输入视图并且在新编辑器上启动输入时调用。这将始终在启动输入(EditorInfo,布尔值)后调用,允许您在此处执行常规设置,并在此处查看特定设置。我们保证在调用此函数之前的一段时间内,onCreateInputView()将被调用
因此,您可以知道要显示的确切输入类型,但切换到这种新键盘类型的实际位置应该是
查看示例应用程序如何处理该功能
@Override public void onStartInput(EditorInfo attribute, boolean restarting) {
super.onStartInput(attribute, restarting);
...
// We are now going to initialize our state based on the type of
// text being edited.
switch (attribute.inputType & InputType.TYPE_MASK_CLASS) {
case InputType.TYPE_CLASS_NUMBER:
case InputType.TYPE_CLASS_DATETIME:
mCurKeyboard = mSymbolsKeyboard;
break;
case InputType.TYPE_CLASS_PHONE:
mCurKeyboard = mSymbolsKeyboard;
break;
case InputType.TYPE_CLASS_TEXT:
mCurKeyboard = mQwertyKeyboard;
...
break;
default:
// For all unknown input types, default to the alphabetic
// keyboard with no special features.
mCurKeyboard = mQwertyKeyboard;
}
}
@Override public void onStartInputView(EditorInfo attribute, boolean restarting) {
super.onStartInputView(attribute, restarting);
// Apply the selected keyboard to the input view.
setLatinKeyboard(mCurKeyboard);
...
}
private void setLatinKeyboard(LatinKeyboard nextKeyboard) {
final boolean shouldSupportLanguageSwitchKey =
mInputMethodManager.shouldOfferSwitchingToNextInputMethod(getToken());
nextKeyboard.setLanguageSwitchKeyVisibility(shouldSupportLanguageSwitchKey);
mInputView.setKeyboard(nextKeyboard);
}
我相信阿齐兹比基安是正确的。您需要更改代码以添加onStartInputView()
。它看起来像这样@Override public void onStartInputView(EditorInfo信息,布尔重新启动){super.onStartInputView(属性,重新启动);loadCurrentKeyboard();kv.setKeyboard(mKeyboardCurrent);}下面是一个简单数字键盘和文本键盘的工作代码。请注意,InputType.TYPE\u MASK\u CLASS
仅用于整个类型。如果需要更具体的类型,如InputType.type\u TEXT\u VARIATION\u peopologic
,则不会使用此掩码。还有一个类型\u掩码\u变体
。
@Override public void onStartInput(EditorInfo attribute, boolean restarting) {
super.onStartInput(attribute, restarting);
...
// We are now going to initialize our state based on the type of
// text being edited.
switch (attribute.inputType & InputType.TYPE_MASK_CLASS) {
case InputType.TYPE_CLASS_NUMBER:
case InputType.TYPE_CLASS_DATETIME:
mCurKeyboard = mSymbolsKeyboard;
break;
case InputType.TYPE_CLASS_PHONE:
mCurKeyboard = mSymbolsKeyboard;
break;
case InputType.TYPE_CLASS_TEXT:
mCurKeyboard = mQwertyKeyboard;
...
break;
default:
// For all unknown input types, default to the alphabetic
// keyboard with no special features.
mCurKeyboard = mQwertyKeyboard;
}
}
@Override public void onStartInputView(EditorInfo attribute, boolean restarting) {
super.onStartInputView(attribute, restarting);
// Apply the selected keyboard to the input view.
setLatinKeyboard(mCurKeyboard);
...
}
private void setLatinKeyboard(LatinKeyboard nextKeyboard) {
final boolean shouldSupportLanguageSwitchKey =
mInputMethodManager.shouldOfferSwitchingToNextInputMethod(getToken());
nextKeyboard.setLanguageSwitchKeyVisibility(shouldSupportLanguageSwitchKey);
mInputView.setKeyboard(nextKeyboard);
}