EditText 软键盘弹出方式探究 以及手动解决浸入式布局软键盘不顶起输入框或者顶掉整个UI的问题


EditText 如何处理软键盘与输入框的现显示隐藏关系  还有位置关系 通过设置windowSoftInputMode

  windowSoftInputMode 还有下列属性

  stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置

  stateUnchanged:当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示

  stateHidden:用户选择activity时,软键盘总是被隐藏

  stateAlwaysHidden:当该Activity主窗口获取焦点时,软键盘也总是被隐藏的

  stateVisible:软键盘通常是可见的

  stateAlwaysVisible:用户选择activity时,软键盘总是显示的状态

  adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示

  adjustResize:该Activity总是调整屏幕的大小以便留出软键盘的空间

  adjustPan:当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分


以上包括两种属性:state是软键盘的可见/隐藏 策略调整,adjust是界面对于软键盘出现的界面控件调整方式,
                              两种属性在Manifest中同时使用时 以 | 分隔。
使用方法 (以adjustPan为例):
      通过设置windowSoftInputMode=adjustPan 或者 在activity的oncreate中setContentView之前写上getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);


1. 一般情况下 ,我们使用windowSoftInputMode=adjustResize来保证点击EditText的时候弹出软键盘并顶起输入框,
   adjustResize的调整UI方式是将  从屏幕底部往上一直到选中的EditText  的这一部分控件顶起,其他部分控件不变

2.如果使用 windowSoftInputMode=adjustPan,也会在点击 EditText后弹出软键盘并将输入框顶起,
但是并不会显示输入框以下的部分 ,就是说此时输入框的位置正好贴在弹出的软键盘上方,如果输入框的下方还有内容的话,是会被软键盘遮挡的 ,而且,最重要的一点,软键盘是通过粗暴地顶起整个UI的方式来占位的,这个时候很可能你就发现你的导航栏一起被顶不见了。所以这么粗暴的调整方式我觉得应该是不大适用的

3.如果是使用沉浸式布局的话,又发现使用adjustResize根本无法顶起EditText,输入框还是会被遮挡,如果使用adjustPan,整个UI又被顶的很难看。。。
  
4.哼,跟他搞这些花里胡哨的,烦了 ,我决定来硬的 我的项目布局是使用了沉浸式的,还是使用windowSoftInputMode=adjustResize
但是不顶出EdiText怎么办呢,那就自己实现监听软键盘的弹出,在键盘弹出后使用属性动画将EdiText移动到软键盘上方,并且在软键盘回收后再将ediText回复到原来的位置
       这里的重点是监听到软键盘的弹出与回收,方法如下,这个方法的参数就是DectorView,可以通过布局内的任意一个View的
getRootView()方法得到。当软键盘出现时必然会将这个rootView覆盖,我们通过rootView.getWindowVisibleDiplayFrame()获得被覆盖后可见界面的Rect,并且通过rootView.getBottom()获得它原本的bottom坐标。很容易就得到覆盖在UI表面的软键盘的高度,这里我们主要是观察这个预设软键盘的最小高度为100dp,只要弹出高度大于这个值,我们就认为软键盘已经弹出了,并且使用属性动画将输入框所在控件移动适当高度,如果输入框在底部的话,只需向上移动这个高度即可

 * 得到的Rect就是根布局的可视区域,而rootView.bottom是其本应的底部坐标值,
 * 如果差值大于我们预设的值,就可以认定键盘弹起了。这个预设值是键盘的高度的最小值。
 * 这个rootView实际上就是DectorView,通过任意一个View再getRootView就能获得。
 */
private boolean isKeyboardShown(View rootView) {
    final int softKeyboardHeight = 100;
    Rect r = new Rect();
    rootView.getWindowVisibleDisplayFrame(r);
    DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
    int heightDiff = rootView.getBottom() - r.bottom;
    Log.e("hahah", heightDiff + "");
    return heightDiff > softKeyboardHeight * dm.density;
}


这里我们给DectorView添加一个GlobalLayoutListener,当它的可视状态发生变化的时候,就会调用onGlobalLayout,我们在这里判断软键盘的弹出与否并测量软键盘高度,调用属性动画相应地移动EditText所在控件

private void setListenerToRootView() {
   
    rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            boolean isOpen = isKeyboardShown(back.getRootView());
            if(isOpen){

                ObjectAnimator.ofFloat(editBar,"translationY",0,-height).setDuration(100).start();
                haveChanged=true;

            }else{
                if(haveChanged) {
                    ObjectAnimator.ofFloat(editBar, "translationY", -height, 0).setDuration(100).start();
                }
            }
        }
    });
}

哈哈哈哈哈 搞定收工






  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值