在Android中,是否有一种方法可以在运行时获取设备上显示的虚拟键盘的高度?实际上,我想在键盘上方显示一个文本框。
我的解决方案是结合了上述所有解决方案。这个方法也有些取巧,但解决了问题(至少对我来说是这样的)。
android:windowSoftInputMode="adjustResize"
标志,就像@bill建议的那样。现在主要部分在于onGlobalLayout()
。在那里,我计算临时视图y轴和根视图高度之间的差异
final View view = findViewById(R.id.base);
view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int rootViewHeight = view.getRootView().getHeight();
View tv = findViewById(R.id.temp_view);
int location[] = new int[2];
tv.getLocationOnScreen(location);
int height = (int) (location[1] + tv.getMeasuredHeight());
deff = rootViewHeight - height;
// deff是软键盘的高度
}
});
但是,为了解决@zeeshan0026的问题,只需要在清单文件中添加一个标志 android:windowSoftInputMode="adjustResize"
就足够了。
android:windowSoftInputMode="adjustNothing"
可以获取键盘高度吗? - VijayRajgetHeightDifference()
函数计算软/虚拟键盘顶部可见框架的高度与屏幕高度之间的差值。我发现,在第一次创建布局时,在EditText聚焦并打开键盘之前,高度差将取决于Android系统导航栏是否显示在设备屏幕内。因此,如果导航栏在屏幕外,则heightDifference
的值为0;如果导航栏在屏幕内,则大于0。我使用一个Integer对象的systemNavigationBarHeight
变量(而不是使用原始的int
数据)来保存该高度差的第一个值,并进行一次初始化,我假设这是Nav Bar的高度。systemNavigationBarHeight
的值以获取软键盘的实际高度。希望这对正在寻找答案的人有所帮助。public class MyActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
rootView.getViewTreeObserver()
.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
private Integer systemNavigationBarHeight = null;
@Override
public void onGlobalLayout() {
int heightDifference = getHeightDifference();
if (heightDifference > 0) {
if (systemNavigationBarHeight == null) {
/* Get layout height when the layout was created at first time */
systemNavigationBarHeight = heightDifference;
}
} else {
systemNavigationBarHeight = 0;
}
if (heightDifference > getDefaultNavigationBarHeight()) {
/* Keyboard opened */
int keyBoardHeight = heightDifference - systemNavigationBarHeight;
} else {
/* Keyboard closed */
}
}
}
}
private int getHeightDifference() {
Point screenSize = new Point();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
getWindowManager().getDefaultDisplay().getRealSize(screenSize);
} else {
getWindowManager().getDefaultDisplay().getSize(screenSize);
}
Rect rect = new Rect();
rootView.getWindowVisibleDisplayFrame(rect);
return screenSize.y - rect.bottom;
}
private int getDefaultNavigationBarHeight() {
int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
return getResources().getDimensionPixelSize(resourceId);
}
return 100;
}
}
2023解决方案
如果您使用androidx.compose.foundation
,您可以轻松获取IME可见性和高度(底部),如下所示:
val imeVisible = WindowInsets.isImeVisible
val bottom = WindowInsets.ime.getBottom(LocalDensity.current)
设置步骤,您可以 观看此视频 或者:
在你的活动的 onCreate
方法中:
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
WindowCompat.setDecorFitsSystemWindows(window, false)
AndroidManifest.xml
<application ... android:windowSoftInputMode="adjustResize">
Themes.xml
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
不用再找了! 我已经寻找这个问题的解决方案很长时间了。在尝试了SOF上所有建议的技巧数天后,我终于找到了完美的解决方案。
这个GitHub项目以最好的方式演示了它: https://github.com/siebeprojects/samples-keyboardheight
玩得开心!
@RequiresApi(Build.VERSION_CODES.R)
private fun getKeyboardHeight(view: View): Int {
return view.rootWindowInsets.getInsets(WindowInsetsCompat.Type.ime()).bottom -
getNavBarHeight(view)
}
@RequiresApi(Build.VERSION_CODES.R)
private fun getNavBarHeight(view: View): Int {
return view.rootWindowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom
}
@RequiresApi(Build.VERSION_CODES.R)
private fun isKeyboardVisible(insets: WindowInsets): Boolean {
return insets.isVisible(WindowInsetsCompat.Type.ime())
}
bottom
值,然后添加一个TreeView Observer并将新的底部值与存储的值进行比较。使用android:windowSoftInputMode="adjustResize"
。private var bottom: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val rect = Rect()
this.window.decorView.getWindowVisibleDisplayFrame(rect)
this.bottom = rect.bottom
this.window.decorView.viewTreeObserver.addOnGlobalLayoutListener {
val newRect = Rect()
this.window.decorView.getWindowVisibleDisplayFrame(newRect)
// the answer
val keyboardHeight = this.bottom - newRect.bottom
// also
if (newRect.bottom < this.bottom) {
//keyboard is open
} else {
//keyboard is hide
}
}
}