【发布时间】:2015-08-10 15:41:43
【问题描述】:
有很多关于查找显示/隐藏软键盘事件的帖子。 我发现自己需要在片段中根据软键状态更改图标。
我尝试实现 onMeasure,但我无法在我的片段中覆盖它。 是否有一种(相对)无痛的方法可以在我的片段中获得干净的显示/隐藏软键盘事件,还是应该放弃发货?
【问题讨论】:
标签: android android-softkeyboard
有很多关于查找显示/隐藏软键盘事件的帖子。 我发现自己需要在片段中根据软键状态更改图标。
我尝试实现 onMeasure,但我无法在我的片段中覆盖它。 是否有一种(相对)无痛的方法可以在我的片段中获得干净的显示/隐藏软键盘事件,还是应该放弃发货?
【问题讨论】:
标签: android android-softkeyboard
可悲但真实 - android 没有本地软件键盘显示事件。
处理键盘隐藏事实的一种方法是检查输入的符号并按下返回按钮(例如 textEdit 将接收甚至返回按钮) - 但它不够灵活的解决方案。
另一个可能的解决方案是: 在活动中覆盖 onMeasure 然后通知观察者(模式观察者) - 例如片段。 Fragment 应该自己订阅和取消订阅 onPause onResume 事件。类似的活动代码:
private class DialogActivityLayout extends LinearLayout {
public DialogActivityLayout(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.activity_dialog, this);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int proposedHeight = MeasureSpec.getSize(heightMeasureSpec);
final int actualHeight = getHeight();
/* Layout loaded */
if (actualHeight == 0 || proposedHeight == actualHeight) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
if (proposedHeight > actualHeight) {
DialogActivity.this.onKeyboardHide();
} else {
DialogActivity.this.onKeyboardShow();
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
我不确定,但我记得它仅适用于 LinearLayout,当然活动应该设置 adjustResize 标志(以编程方式或在清单中)
另一种(我认为更好的方法)是使用 globalTree 观察者
SoftKeyboard open and close listener in an activity in Android?
【讨论】:
经过一番努力,我能够抽象出一种方法,我可以在需要显示或隐藏键盘时调用该方法,而无需使用我在许多答案中看到的SHOW_FORCED,即使在新的答案中,结果也会是键盘打开没有文本输入的活动。
我在 onGlobalLayout 中使用了这个code 来检查键盘是否打开,然后在我的方法中决定是打开还是关闭。
代码如下:
检查它是否打开:
private static boolean isKeyboardVisible(Activity activity) {
Rect r = new Rect();
View contentView = activity.findViewById(android.R.id.content);
contentView.getWindowVisibleDisplayFrame(r);
int screenHeight = contentView.getRootView().getHeight();
int keypadHeight = screenHeight - r.bottom;
return (keypadHeight > screenHeight * 0.15);
}
执行我需要的操作(这里是我调用上述方法的地方):
public static void toggleKeyboard(final Activity activity, final boolean showKeyboard) {
final InputMethodManager imm =
(InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
// The Handler is needed because the method that checks if the keyboard
// is open need some time to get the updated value from the activity,
// e.g. when my activity return to foreground.
new Handler().postDelayed(new Runnable() {
public void run() {
// This 'if' just check if my app still in foreground
// when the code is executed to avoid any problem.
// I've leave out of the answer to keep short, you may use your own.
if(Tools.isAppInForeground(activity)) {
// Check the keyboard.
boolean isVisible = isKeyboardVisible(activity);
// If I want to show the keyboard and it's not visible, show it!
if (showKeyboard && !isVisible) {
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT,
InputMethodManager.HIDE_IMPLICIT_ONLY);
// If I want to hide and the keyboard is visible, hide it!
} else if (!showKeyboard && isVisible) {
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
}
}
}
}, 100);
}
要使用,我只是这样调用:
toggleKeyboard(myactivity, true); // show
// or
toggleKeyboard(myactivity, false); // hide
【讨论】: