本文正在参加「金石计划 . 分割6万现金大奖」

前言

之前写过一篇文章,有讲怎么处理Android输入框软键盘挡住的问题,无论是原生的还是webview的,这儿边首要的问题是webview的问题比较难处理,没有看过的能够先看看 /post/715437… ,首要是issue 5497这个问题。然后或许有些朋友觉得,这篇文章没能处理他的问题,或许说依照我的代码去写又会呈现新的问题。这阐明没有能了解这篇文章写的内容,我仅仅举了一个自己碰到的场景,然后去剖析,为什么会这样,并用一些源码告知你为什么这样写的能处理。可是并不是所有的场景去套这个代码都是正常的,不过假如你了解其间的一些原理的话,你至少能有个方向知道该从何下手去处理你自己碰到的场景。

假如看不懂没关系,我这次讲慢点,再去慢慢剖析更多的场景,可是有一点要记住,我对这个问题的处理不是万金油,你有必要要有必定的了解,知道一个方向,再去处理自己碰到的场景,不要直接套代码。 这儿剖析的问题便是issue 5497这个问题。

issue 5497问题

咱们再简单回忆一下这个问题,原生的软键盘和输入框的冲突,直接设置window的softInputMode就能处理,这个很简单。可是假如输入框是webview内部H5的输入框的状况下pan会失效,只能用resize。并且,假如是这个window是概念上全屏的状况下(设置全屏的办法很多),resize也会失效。

我上一篇文章中,我碰到的问题的场景是: 一个Dialog,里边的根页面设置了沉溺形式,根布局下有一个webview,webview中有个输入框,点击输入框时弹出软键盘会挡住输入框。

咱们先剖析,为什么会挡住输入框?由于默认的softInputMode在正常状况下会顶起输入框,可是webview会失效,那咱们就把softInputMode设成SOFT_INPUT_ADJUST_RESIZE

然后发现没作用,为什么没作用?由于我的Dialog是全屏的,并且设置了沉溺形式,所以符合了全屏状况下resize也会失效这个条件。注意这个全屏能够了解成指的是概念上的全屏,不是咱们视觉作用上的全屏,也便是这时去设置marginTop,经过这些办法去改动视觉上不是全屏是不会有作用的。

咱们的思路便是破解让这个window变成非全屏。 从上一篇文章能够看出,咱们用的办法是设置fitSystemWindows,经过fitSystemWindows设置为true,来破解沉溺形式导致的全屏作用,原理是什么?经过上一篇文章知道,原理是设置一个安全间隔,可是这个安全间隔会导致你的window被压缩,所以咱们要重写view的fitSystemWindows办法设置安全间隔去避免window被压缩

@Override
protected boolean fitSystemWindows(Rect insets) {
    insets.top = 0;
    return super.fitSystemWindows(insets);
}

而这个问题的处理思路是经过设置fitSystemWindows去打破全屏这个条件,从而使SOFT_INPUT_ADJUST_RESIZE能对webview生效。 这是重点的一步,后续的操作都是为了处理fitSystemWindows所带来的影响。

布局顶起后间隔软键盘有必定间隔

一般咱们的布局顶起后底部也是紧贴软键盘,有的朋友或许会说,为什么我也这样做了,可是我webview布局被软键盘顶起之后间隔软键盘会存在一部分的间隔。

假如你不知道这个问题,阐明对softInputMode不太了解,虽然我个人对这个了解也不是很深,可是假如你能运用SOFT_INPUT_ADJUST_PAN的话,就必定不会呈现这个问题,可是用SOFT_INPUT_ADJUST_RESIZE的话,就会在某些布局中有这个问题,可惜上面说了,webview对SOFT_INPUT_ADJUST_PAN无效。

这是为什么呢?由于简单来说SOFT_INPUT_ADJUST_PAN是顶起你的输入框,而SOFT_INPUT_ADJUST_RESIZE会把window给顶起来。所以假如你是window全屏并且webview也是全屏的状况就不会遇到这个问题(这儿其实也就高度影响,宽度不影响),但假如你是window中的webview间隔window的底部有必定的间隔,这时候用SOFT_INPUT_ADJUST_RESIZE顶起来就会和输入法有一段间隔。

那这个问题要怎么处理,这个处理的办法很多,比方经过逻辑手段,或许调整webview大小之类的,这个就没什么好说的了。

Activity的webview输入框被挡

上一篇文章包括上面有讲我在Dialog中的webview的场景的处理方案。有的朋友会说我activity的webview也是这样的,可是依照你这个代码写进去没有作用,我分明也给window设置了SOFT_INPUT_ADJUST_RESIZE,也给view设置了setFitsSystemWindows,也重写了fitSystemWindows办法设置top,可是没作用。

这就阐明你还没了解为什么会呈现这个问题,你仅仅期望随便去找个文章拷代码下来用,代码有用就觉得这个作者牛逼,代码没作用就觉得这个作者傻逼。好,哪怕你是不看为什么,只想考代码,套到你运用的地方没作用,那为何不问问为什么没作用,你能够在评论区留言,说你是什么样的场景,运用这个代码没作用。写一两句留言对你来说也并不耗多少时间,我仅仅觉得,处理问题,需求知道一个方向,不能一味的只想抄答案,这样去处理问题是很消耗时间的,并且这样处理问题也或许会呈现其它的问题。

有点扯远了,话说回来,为什么上面的代码对Activity或许没作用。假如仔细看都知道,我说了形成SOFT_INPUT_ADJUST_RESIZE失效的原因是全屏,而我上面Dialog的场景,形成全屏的操作是设置了沉溺形式,所以setFitsSystemWindows是为了处理沉溺形式导致全屏的状况。而你的Activity的全屏,不必定是沉溺形式形成的,所以你运用setFitsSystemWindows会无效。

还看不懂没关系,再举个比如。你给你的activity设置Fullscreen的主题theme也会导致全屏,这时候给window设置SOFT_INPUT_ADJUST_RESIZE无效,咱们的思路是怎么去破解Fullscreen这个主题形成的全屏。咱们能够动态去概念theme,行不行?当然能够,可是这个机遇要写对。咱们也能够用window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)去破解全屏的作用嘛。可是这个clearFlags假如对你的需求形成了影响,你还要经过其它办法去消除这个影响,这种就具体剖析具体处理了,没有标准的答案。

总结

写这篇文章首要是想阐明,这个webview被输入法挡住的问题,这个issue 5497,是一个比较费事的问题,它不是光靠随便在网上去抄个代码就能处理的。包括你或许会去经过监听输入法的弹出去核算翻滚的高度,这种办法理论上是不难,实际去开发也是要做一些细节处理和兼容的。

这篇文章没有贴多少代码,首要讲一个处理问题的思路。要去了解这个问题是为什么发生的,知道一个方向,才能去更好的处理问题,你能够不依照我的代码去写,可是你知道处理问题的方向后,你甚至能自己经过合适自己事务的逻辑代码去处理你的问题。

我不确保我对整个问题的了解是完全正确的,可是假如有大佬觉得我的了解有问题,能够指出,我也期望能这样,这样反而让我印象更深入。可是假如有人想不了解这些内容的状况下经过去找别人的代码去碰运气来处理问题,那我也只能祝你好运。