我有一个视图为我处理输入,我弹出一个键盘并设置视图可聚焦。现在我可以得到某些按键...
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DEL) {
} else if (keyCode == KeyEvent.KEYCODE_BACK) {
} else if (keyCode == KeyEvent.KEYCODE_ENTER) {
} else {
}
}
等等……我使用的字符被按下。
event.getDisplayLabel()
只要我只想要普通的字母A-Z,这就行了。在其他语言中,长按软键盘上的普通字母可以访问更多字母…但是,onKeyDown/Up无法检测到这些替代字母。我只能检测到正常的字母,软键盘的标签。现在我的应用程序必须处理外国输入和字母,我已经将键盘改为土耳其语,并且我可以在键盘上找到类似于“íüöó”的字母,但如果我按下它们,我不会得到任何响应。与事件无关。getDisplayLabel或事件。获取Unicode字符();如何检测这些字母?
当键盘打开时,onKeyDown()
和 onKeyUp()
方法无法正常工作,因为 Android 将屏幕键盘视为单独的活动。
实现所需内容的最简单方法是在视图上重写 onKeyPreIme()
方法。例如,如果您尝试从编辑文本中捕获 onKeyDown,请创建一个扩展编辑文本
的新类,并重写 onKeyPreIme()
方法:
public class LoseFocusEditText extends EditText {
private Context mContext;
protected final String TAG = getClass().getName();
public LoseFocusEditText(Context context) {
super(context);
mContext = context;
}
public LoseFocusEditText(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
public LoseFocusEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
}
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//hide keyboard
InputMethodManager mgr = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(this.getWindowToken(), 0);
//lose focus
this.clearFocus();
return true;
}
return false;
}
}
这是在kitkat / htc one上测试的。
编辑:
我不确定是什么原因导致onKeyDown根本没有被调用。也许是你的观点有问题?因为这个可能会有比我的解决方案更好的答案。无论哪种方式,这都可能奏效:
在活动级别覆盖dispatchKeyEvent,而不是使用视图中的onKeyDown。这将在到达窗口管理器之前处理您的键事件,因此请确保对任何未显式处理的键事件调用super。
使用ACTION_DOWN的示例(因为每个事件都有ACTION_UP和ACTION_DOWN),因为您的示例使用了onKeyDown:
@Override
public boolean dispatchKeyEvent(KeyEvent event){
if(event.getAction() == KeyEvent.ACTION_UP) {
return super.dispatchKeyEvent(event);
}
if (keyCode == KeyEvent.KEYCODE_DEL) {
} else if (keyCode == KeyEvent.KEYCODE_BACK) {
} else if (keyCode == KeyEvent.KEYCODE_ENTER) {
} else {
return super.dispatchKeyEvent(event);
}
}
现在(很抱歉)
你可以试试:
char key = (char)event.getUnicodeChar();
而不是
char key = event.getDisplayLabel();
getDisplayLabel()将只提供键盘上显示的键,正如您所指出的,该键不一定是用户选择的字符。
明白了:)
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(event.getAction()==KeyEvent.ACTION_DOWN) return true;
if(keyCode==KeyEvent.KEYCODE_ALT_LEFT || keyCode==KeyEvent.KEYCODE_ALT_RIGHT || keyCode==KeyEvent.KEYCODE_SHIFT_LEFT || keyCode==KeyEvent.KEYCODE_SHIFT_RIGHT) return true;
if (keyCode == KeyEvent.KEYCODE_DEL) {
doBackspace();
return true;
} else if (keyCode == KeyEvent.KEYCODE_BACK) {
if(this.avl!=null) this.avl.onInputCancelled(this);
return false;
} else if (keyCode == KeyEvent.KEYCODE_ENTER) {
inputstarted=false;
if(this.avl!=null) this.avl.onInputFinished(this,this.text,celldata);
return true;
}
String key = "";
if (event.getAction()==KeyEvent.ACTION_UP) key = String.valueOf((char)event.getUnicodeChar()).toUpperCase();
else if (event.getAction()==KeyEvent.ACTION_MULTIPLE) key = String.valueOf(event.getCharacters()).toUpperCase();
return process(key);
}
重要的部分是阻止ALT_LEFT/SHIFT_LEFT/etc键码,区分ACTION_UP/ACTION_MULTIPLE,使用event.getUnicodeChar()或event.getCharacters()。
它现在工作,我可以在手机上获得所有的字符,甚至KEYCODE_DEL工作。但是在平板电脑上,我仍然没有收到删除键的回调。似乎是一个坏错误,因为今天早上它甚至在平板电脑上也工作得很好。