Android 处理软键盘弹出问题

引发的问题

键盘弹出后和界面互相作用一般有如下问题:

  • 键盘遮挡你想看到的内容

  • 键盘压缩你的界面变形

  • 键盘自动弹出

  • 键盘把界面顶出窗口

暂时想到这几种情况,由于最近做一个聊天的软件,遇到一些问题,所以想把类似问题全搞清楚,解决方法做如下总结。

1. 先看看各种情况下,键盘对界面干了啥都。

这里写图片描述这里写图片描述

默认情况
默认情况,输入法只管顶起你点击的输入框,保证这个输入框能方便的输入,这是它的核心任务,其他的不管,如上第一个图。

那么这时候它到底做了什么操作呢,我们可以多放点控件上去观察:

这里写图片描述这里写图片描述

通过上面两幅图比较,我们从背景的情况来看,界面没有被压缩,而且把最上面的控件搞没了,说明是把整个界面顶上去了。

然后再看两幅图:
这里写图片描述这里写图片描述

这两幅图的界面是添加了scrollview的,那么其他情况不变的情况下,效果发生了变化,为了使编辑框刚好输入,背景图被压缩了,但是最上边没有放入scrollview的控件却没有被顶上去。

这两次对比,可以得出结论:默认情况下没有scrollview、listview等控件的界面上,弹出键盘会直接将整个界面原封不动的往上顶,直到可以方便输入;而有scrollview等滚动控件的界面,弹出键盘会压缩这部分可滚动控件,直到可以方便输入。当然并不是只压缩这个滚动控件,而是和它重叠的部分界面都跟着压缩,因为那个背景图片并不是scrollview的背景,而是父控件的

以上是默认情况,我们知道activity标签中可以配置一个android:windowSoftInputMode参数,对压缩界面有影响的是这几个值:

adjustResize
adjustPan
adjustNothing
adjustUnspecified

除了这几个值还有其他值,这里不做介绍。

接着用这种方法测试这几个值,发现如下结论:

  • adjustResize:

    有滚动控件,会压缩滚动控件来保证输入框刚好输入;而没有滚动控件,不保证正好能输入,其实就是只管自己顶上来,盖住谁算谁。而且无论界面有没有可滚动控件,都将压缩父布局控件。键盘会自动弹出。

  • adjustPan:

    如果输入框高于键盘弹出的高度,那不会对界面造成任何影响,也不会压缩背景图等。如果输入框低于键盘弹出高度,不管有没有滚动控件,不会压缩任何界面,会把整个界面往上顶。键盘不自动弹出。

  • adjustNothing:

    不做任何事,不管有没有滚动控件,能不能正确输入,什么都不会做。键盘不自动弹出。

  • adjustUnspecified:

    这个其实就是不填值的默认值,现象上面已经详细说过,通过对比可以发现,其实就是根据有没有滚动控件,自动选择了adjustPan和adjustResize这两种情况。这个值其实最大保证了能使输入框刚好方便输入。但是最大程度保证了这一点,也就意味着,最大程度的不会顾及其他控件的情况。

2 遇到显示不理想的情况如何处理

通过上面我们知道了各种情况下键盘对界面的影响情况。那么如果遇到问题,如何解决呢。

1 键盘自动弹出的情况,上面已经分析,通过调整android:windowSoftInputMode,可以容易的解决。

2 控件压缩的情况,设置adjustPan,不会压缩任何界面

3 控件被顶出界面外,肯定是设置了adjustPan,改为别的就行了

其实2和3已经冲突,想要不压缩,又不整个往上顶,输入框高的话还好,低的话,那肯定就遮挡了。所以我们重点解决遮挡问题。

  • 适当选择android:windowSoftInputMode值:如果输入框较高,又不希望压缩界面及控件,适合adjustPan;如果希望方便输入,还能不遮挡其他控件,那可以选择adjustResize,然后通过适当的把一些控件放到滚动控件中,并在键盘弹出后,适当滚动控件到合适位置。或者当键盘弹出后,向上平移某个控件,键盘落下后,再移动回来。

这里提供几个函数,因为解决遮挡问题,需要两个关键因素:监听键盘弹出,测量键盘高度

监听键盘弹出:

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;
    return heightDiff > softKeyboardHeight * dm.density;
}

view.getRootView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if(isKeyboardShown(recyclerView.getRootView())){
                recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount()-1);
            }
        }
    });

这就是在rootview上加一个布局变化的监听,监听到布局变化,就判断是否键盘弹出,判断标准是,rootview的底部和窗口底部的距离差,这个距离差就是键盘的高度。我们可以设置大于多少就算是键盘弹出了。

获取键盘高度:

private int getKeyboardHight(View rootView){
    Rect r = new Rect();
    rootView.getWindowVisibleDisplayFrame(r);
    DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
    int heightDiff = rootView.getBottom() - r.bottom;
    return heightDiff;
}

有了这些基础,可以适当的滑动滚动控件,适当的平移控件了。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值