我想根据是否显示虚拟键盘来改变布局。我已经搜索了API和各种博客,但似乎找不到任何有用的东西。
这可能吗?
谢谢!
我想根据是否显示虚拟键盘来改变布局。我已经搜索了API和各种博客,但似乎找不到任何有用的东西。
这可能吗?
谢谢!
当前回答
就像@amalBit的答案一样,注册一个全局布局的监听器,并计算dectorView的可见底部和建议底部的差值,如果差值大于某个值(猜测IME的高度),我们认为IME是up的:
final EditText edit = (EditText) findViewById(R.id.edittext);
edit.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (keyboardShown(edit.getRootView())) {
Log.d("keyboard", "keyboard UP");
} else {
Log.d("keyboard", "keyboard Down");
}
}
});
private boolean keyboardShown(View rootView) {
final int softKeyboardHeight = 100;
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
int heightDiff = rootView.getBottom() - r.bottom;
return heightDiff > softKeyboardHeight * dm.density;
}
高度阈值100是IME猜测的最小高度。
这适用于adjustPan和adjuststresize。
其他回答
隐藏|显示事件键盘可以通过简单的hack在OnGlobalLayoutListener监听:
final View activityRootView = findViewById(R.id.top_root);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
if (heightDiff > 100) {
// keyboard is up
} else {
// keyboard is down
}
}
});
这里activityRootView是Activity的根视图。
桑德,我相信你是想展示被软键盘挡住的视野。试试这个http://android-developers.blogspot.com/2009/04/updating-applications-for-on-screen.html。
Nebojsa Tomcic的回答对我没有帮助。我有RelativeLayout与TextView和AutoCompleteTextView里面。我需要滚动TextView到底部时,键盘显示,当它被隐藏。为了实现这一点,我重写了onLayout方法,它对我来说很好。
public class ExtendedLayout extends RelativeLayout
{
public ExtendedLayout(Context context, AttributeSet attributeSet)
{
super(context, attributeSet);
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.main, this);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
super.onLayout(changed, l, t, r, b);
if (changed)
{
int scrollEnd = (textView.getLineCount() - textView.getHeight() /
textView.getLineHeight()) * textView.getLineHeight();
textView.scrollTo(0, scrollEnd);
}
}
}
2020年更新
这现在是可能的:
在Android 11上,你可以这样做
view.setWindowInsetsAnimationCallback(object : WindowInsetsAnimation.Callback {
override fun onEnd(animation: WindowInsetsAnimation) {
super.onEnd(animation)
val showingKeyboard = view.rootWindowInsets.isVisible(WindowInsets.Type.ime())
// now use the boolean for something
}
})
你也可以听显示/隐藏键盘的动画,并做相应的转换。
我建议阅读Android 11预览版和相应的文档
Android 11之前
但是,这项工作还没有Compat版本,所以您需要求助于黑客。
你可以得到窗口的insets,如果底部的insets大于一些值,你认为是合理的(通过实验),你可以认为这是显示键盘。这不是很好,在某些情况下可能会失败,但没有框架支持这一点。
这是对这个确切问题的一个很好的回答https://stackoverflow.com/a/36259261/372076。或者,这里有一个页面给出了一些不同的方法来实现这个在Android 11之前:
https://developer.salesforce.com/docs/atlas.en-us.noversion.service_sdk_android.meta/service_sdk_android/android_detecting_keyboard.htm
Note
此解决方案不适用于软键盘和 onConfigurationChanged将不会被soft (virtual)调用 键盘。
您必须自己处理配置更改。
http://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange
示例:
// from the link above
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks whether a hardware keyboard is available
if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
Toast.makeText(this, "keyboard visible", Toast.LENGTH_SHORT).show();
} else if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
Toast.makeText(this, "keyboard hidden", Toast.LENGTH_SHORT).show();
}
}
然后只需更改一些视图的可见性,更新字段,并更改布局文件。
尽管本页上投票最多的解决方案说,有一个setWindowInsetsAnimationCallback的ViewCompat版本一直工作到Android 21。
所以现在,这个解决方案的方法一直适用于21。
来源:https://developer.android.com/reference/androidx/core/view/ViewCompat setWindowInsetsAnimationCallback (android.view.View androidx.core.view.WindowInsetsAnimationCompat.Callback)