我正在使用Navigation
中的Jetpack
。这意味着,我只有1个活动,并且每当键盘弹出时,我都希望将布局向上移到键盘上。问题是,这仅应在某些Fragment
上发生。
在Manifest
上进行设置有效,问题在于我仅在特定的Fragment
上需要它。
android:windowSoftInputMode="adjustResize"
该应用具有一个BottomNavigationView
,因此,为了保留Fragment
状态,我隐藏了而不是替换和删除它。另外,每个片段都有其NavigationGraph
。因此,我无法明确访问生命周期。我认为以编程方式设置该模式将起作用。但是,正如所解释的,没有。
override fun onResume() {
super.onResume()
keyboardMode = requireActivity().window.attributes.softInputMode
requireActivity().window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
}
override fun onPause() {
super.onPause()
keyboardMode?.let { requireActivity().window.setSoftInputMode(it) }
}
我也尝试在XML上进行设置:
android:fitsSystemWindows="true"
它没有用。另外,我应该在哪个嵌套片段上放它?
有什么想法吗?我能做什么?有没有一种方法可以获取键盘的大小,使用监听器或类似工具将片段的内容移至键盘的大小上?只能以这种方式解决该问题...
编辑:
我找到了this,可以根据需要进行更改:
class KeyboardListener(
private val binding: FragmentWebviewBinding,
private val listener: KeyboardInterface
) {
private var keyboardListenersAttached = false
private var rootLayout: ViewGroup? = null
private val keyboardLayoutListener = OnGlobalLayoutListener {
val r = Rect()
binding.webview.getWindowVisibleDisplayFrame(r)
val screenHeight = binding.root.rootView.height
// r.bottom is the position above soft keypad or device button.
// if keypad is shown, the r.bottom is smaller than that before.
val keypadHeight = screenHeight - r.bottom
logD("Keyboard", "keypadHeight = $keypadHeight")
if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height.
// keyboard is opened
listener.onShowKeyboard(keypadHeight)
} else {
// keyboard is closed
listener.onHideKeyboard()
}
}
fun attachKeyboardListeners() {
if (keyboardListenersAttached) return
rootLayout = binding.root as ViewGroup?
rootLayout?.viewTreeObserver?.addOnGlobalLayoutListener(keyboardLayoutListener)
keyboardListenersAttached = true
}
fun destroy() {
if (keyboardListenersAttached) {
rootLayout?.viewTreeObserver?.removeGlobalOnLayoutListener(keyboardLayoutListener)
}
}
interface KeyboardInterface {
fun onShowKeyboard(keyboardHeight: Int)
fun onHideKeyboard()
}
}
我对监听器所做的事情是:如果键盘被打开,我将添加keyboardHeight
的底边距,如果被关闭,则返回0。问题是,这不能正确测量。我不确定是否从px
到dp
或其他类似名称。而且,它一直都在被调用。
但这是迄今为止最好的方法。
编辑2: 我测量不正确。
正确的解决方案是更改keyboardLayoutListener
上的以下行:
binding.webview.getWindowVisibleDisplayFrame(r)
val screenHeight = binding.root.height
尽管我只在Webview的填充上移动,工具栏仍在向上移动:
override fun onHideKeyboard() {
with(binding.webview) {
val params = layoutParams as ConstraintLayout.LayoutParams
params.setMargins(0, 0, 0, 0)
layoutParams = params
}
}
override fun onShowKeyboard(keyboardHeight: Int) {
with(binding.webview) {
val params = layoutParams as ConstraintLayout.LayoutParams
params.setMargins(0, 0, 0, keyboardHeight)
layoutParams = params
}
}