Dialog布局中拥有EditText时监听软键盘的弹出和收起

最近在做项目的时候,遇到了一个需求:点击按钮在屏幕中间弹出一个弹窗,弹窗上面有一个输入框。对于这个需求我采用Dialog+EditText来实现,功能并不难实现。但是UI老师要求在没有进行输入的时候,弹窗位置在屏幕中间。当进行输入的时候,弹窗位置在上面。
现在的情况是,当输入框调起软键盘时,软键盘会将弹窗中输入框以上的布局进行上移,但是弹窗位置本身不会变化。也就是说,软键盘会遮盖弹窗中输入框下方的布局,而将其上方的布局进行挤压。
在网上看调整软键盘的输入模式后,虽然不会对布局产生挤压,但是却直接盖在了弹窗上面,显然不符合期望。
因此需要调整思路,弹窗的位置随着键盘的收起显示而变化,这意味着我们可以监听软键盘的弹出与收起。但是网上大多监听键盘的解决方案是在Activity或者Fragment中,通过监听整个View树布局的高度变化来判断键盘是否被调起。但是这里采用的是Dialog实现,当Dialog弹出时,整个View树高度就已经发生变化,因此不可行。

在多次尝试之后,找到在Dialog中去监听键盘高度的办法。那就是,首先将Dialog调整成全屏的,如果不是全屏的使用一个占位View。这样也方便我们做后面的移动。将Dialog设置为全屏之后,然后对Dialog的根视图的高度变化来判断是否产生了键盘调起。代码如下
 

viewTreeListener = object :
            ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                //获取当前根视图在屏幕上显示的大小
                val r = Rect()
                view.getWindowVisibleDisplayFrame(r)
                val visibleHeight = r.height()
                // 初始化时,根视图按设置大小显示
                if (rootViewLastVisibleHeight == 0) {
                    rootViewLastVisibleHeight = visibleHeight
                    return
                }
                //根视图显示高度没有变化,可以看作是软键盘显示/隐藏状态没有改变
                if (rootViewLastVisibleHeight == visibleHeight) {
                    return
                }

                //上次显示比目前显示的高度大,可以看作软键盘显示了,200 为键盘的高度
                if (rootViewLastVisibleHeight - visibleHeight > 200) {
                    rootViewLastVisibleHeight = visibleHeight
                    val objectAnimator: ObjectAnimator =
                        ObjectAnimator.ofFloat(
                            binding.submitToEmail,
                            "translationY",
                            0.0f,
                            -420.0f
                        ) //沿着Y轴平移
                    objectAnimator.duration = 0
                    objectAnimator.start()
                }
                //上次显示没有当前显示的高度大,可以看做软键盘隐藏了,200 为键盘的高度
                if (visibleHeight - rootViewLastVisibleHeight > 200) {
                    val objectAnimator: ObjectAnimator =
                        ObjectAnimator.ofFloat(
                            binding.submitToEmail,
                            "translationY",
                            -420.0f,
                            0f
                        ) //沿着Y轴平移
                    objectAnimator.duration = 0
                    objectAnimator.start()
                    rootViewLastVisibleHeight = visibleHeight
                }
            }
        }
        view.viewTreeObserver.addOnGlobalLayoutListener(viewTreeListener)

这样我们就可以在键盘收起与调起的时候做相应的逻辑处理。
当然,在cancel的时候需要移除监听
 

 view.viewTreeObserver.removeOnGlobalLayoutListener(viewTreeListener)
        viewTreeListener = null


 

你可能感兴趣的:(android)