仅在特定片段上打开键盘时才移动布局(WebView)

时间:2020-09-10 19:03:25

标签: android layout keyboard android-lifecycle

我正在使用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。问题是,这不能正确测量。我不确定是否从pxdp或其他类似名称。而且,它一直都在被调用。

但这是迄今为止最好的方法。

编辑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
    }
}

0 个答案:

没有答案
相关问题