前言:这个问题在目前的开发生涯中,令我比较深刻,以至于过去快1年了,我还记忆犹新,在此记录一下。
场景:大约在1年前,当时负责的一个WMS仓储管理APP(Kotlin项目),线上突然反馈了“输入框被软键盘遮挡的问题”。接手问题后,使用线下物联网定制手持机调试复现中,系统版本为Android 8.0。
问题现象:目前暂时没有设备,因而无法复现,故暂时不上gif图。这边口头描述一下:在页面中间部分有一个输入框,点击输入框唤出软键盘时,输入框被软键盘遮挡了一部分,这一部分就看不到了。遮挡程度取决于输入框位置,可能被遮挡部分或被全遮挡;位于页面上方的,比如搜索框之类的,不受影响;对于软件盘输入事件不影响,输入的数据还是能拿到的。
解决:当时遇到这个问题,比较懵逼,且也找不到相关资料,只能不断试错,通过猜测进行尝试,中间也横向对比了其他项目,在该手持机上跑;转折点在“部分遮挡”情况下,部分遮挡的时候,输入的文字、光标都展示了一半,就感觉是可能是渲染问题,于是开启了项目全局硬件加速进行尝试,最终解决了问题。
<application>
...
android:hardwareAccelerated="true"
</application>
总结:一般没有冲突或其它连带问题情况下,硬件加速优先还是开启比较好。如果遇到项目不得不开启硬件加速,而其他地方开启硬件加速会出现问题的情况,则可以结合Application、Activity、Window这三个层面对硬件加速打开或关闭。
Window开启硬件加速:
window.setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)
参数解释如下:
/**
* <p>Indicates whether this window should be hardware accelerated.
* Requesting hardware acceleration does not guarantee it will happen.</p>
*
* <p>This flag can be controlled programmatically <em>only</em> to enable
* hardware acceleration. To enable hardware acceleration for a given
* window programmatically, do the following:</p>
*
* <pre>
* Window w = activity.getWindow(); // in Activity's onCreate() for instance
* w.setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
* WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
* </pre>
*
* <p>It is important to remember that this flag <strong>must</strong>
* be set before setting the content view of your activity or dialog.</p>
*
* <p>This flag cannot be used to disable hardware acceleration after it
* was enabled in your manifest using
* {@link android.R.attr#hardwareAccelerated}. If you need to selectively
* and programmatically disable hardware acceleration (for automated testing
* for instance), make sure it is turned off in your manifest and enable it
* on your activity or dialog when you need it instead, using the method
* described above.</p>
*
* <p>This flag is automatically set by the system if the
* {@link android.R.attr#hardwareAccelerated android:hardwareAccelerated}
* XML attribute is set to true on an activity or on the application.</p>
*/
public static final int FLAG_HARDWARE_ACCELERATED = 0x01000000;