我有一个处理输入的视图,我弹出一个键盘并将视图设置为可聚焦。现在我可以获得某些按键......
@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无法检测到这些替代字母。我只能检测正常的字母,软键盘的标签。 现在我的应用程序必须处理外国输入和字母,我已将键盘更改为土耳其语,我可以在键盘上找到类似í“ú”的字母,但如果我按下它们,我就不会得到任何回复。不是与event.getDisplayLabel或event.getUnicodeChar(); 我该如何检测这些字母?
答案 0 :(得分:3)
当键盘打开时,onKeyDown()
和onKeyUp()
方法无法正常工作,因为Android会将屏幕键盘视为单独的活动。
实现目标的最简单方法是在视图上覆盖onKeyPreIme()
方法。例如,如果您尝试从EditText捕获onKeyDown,请创建一个扩展EditText
的新类,并覆盖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上测试的。
答案 1 :(得分:1)
编辑:
我不确定是什么导致onKeyDown根本不被调用。也许这是你的观点的问题?因此,可能有比我的解决方案更好的答案。不管怎样,这可能有用:
不使用视图中的onKeyDown,而是在活动级别覆盖dispatchKeyEvent。这将在到达窗口管理器之前处理您的键事件,因此请确保在未明确处理的任何键事件上调用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()只会为您提供键盘上显示的键,正如您所指出的那样,键不一定是用户选择的字符。
答案 2 :(得分:1)
知道了:)
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在移动设备上运行。但是在平板电脑上,我仍然没有收到删除密钥的回调。看起来像一个坏的错误,因为今天早上它甚至在平板电脑上工作正常。