Android软键盘遮挡Qml TextField,配置adjustResize无效该如何解决?
我有一个包含header、footer和contentItem的Dialog,其中contentItem为ListView,示例代码如下:
Dialog { width: 200 height: 200 x: 10 y: 100 header: Rectangle { } contentItem: ListView { delegate: TextField { // this is covered by the Android keyboard } } footer: Rectangle { } }
iOS系统中弹出软键盘时,整个屏幕会自动上移,保证ListView中持有光标的TextField始终可见。但在Android系统中,TextField的光标会被软键盘遮挡。我已经尝试在AndroidManifest.xml中设置android:windowSoftInputMode="adjustResize",但没有效果。
请问有没有简便方法可以保证当前持有光标的TextField始终可见?还是只能手动调整Dialog的y坐标来解决?
软键盘隐藏时的Qml界面:
软键盘弹出遮挡光标时的Qml界面:
原生Android文本输入框界面:
原生Android文本输入框软键盘弹出时自动上移界面:
adjustResize不生效的核心原因是Qt Quick Controls 2的Dialog默认是独立于根窗口布局的弹出层,不会自动响应Android的窗口尺寸调整事件,不用完全手动计算y坐标,有两个更简便的方案:
方案1:使用Qt内置InputPane API(推荐,跨平台兼容)
InputPane是Qt提供的跨平台软键盘状态监听API,无需额外适配原生系统逻辑,直接绑定Dialog的位置和ListView的滚动逻辑即可:
import QtQuick.Window 2.3 Dialog { width: 200 height: 200 x: 10 // 软键盘弹出时自动上移Dialog,避免被遮挡 y: 100 - (InputPane.visible ? InputPane.keyboardRectangle.height : 0) header: Rectangle {} contentItem: ListView { id: listView delegate: TextField { onActiveFocusChanged: { if (activeFocus) { // 自动滚动到当前聚焦的输入框,保证光标可见 listView.positionViewAtIndex(index, ListView.Visible) } } } } footer: Rectangle {} }
该方案同时兼容Android和iOS,不需要修改AndroidManifest.xml的配置,就算应用开启了全屏模式也能正常工作。
方案2:调整Dialog布局规则配合adjustResize
如果你的应用没有使用全屏模式,确认adjustResize配置生效时,可以把Dialog的定位方式从固定y值改成相对根窗口底部定位,软键盘弹出时根窗口高度被压缩,Dialog会自动上移:
Dialog { width: 200 // 限制最大高度,避免软键盘弹出后Dialog超出可视区域 height: Math.min(200, rootWindow.height - 40) x: 10 // 相对根窗口底部固定20px边距 y: rootWindow.height - height - 20 }
如果该方案不生效,检查你的Activity主题是否配置了android:windowFullscreen属性,全屏模式下Android系统的adjustResize规则默认失效。
内容的提问来源于stack exchange,提问作者Hyndrix

