webview键盘自适应_Webview中键盘适配的一些坑

在Android原生开发中,使用windowSoftInputMode处理键盘适配时,对于Webview无效,原因是APP设置了状态栏样式。解决方案是使用AndroidBug5497Workaround类。然而,100vh在Android中计算方式不同于iOS,键盘弹起时导致页面压扁。通过JS设置viewport的height解决此问题,开启Webview对viewport的支持,并调整Webview设置。
摘要由CSDN通过智能技术生成

在 Android 原生开发中,可以通过设置 windowSoftInputMode,来处理键盘弹起时 Layout 的适配方式。有两种方案,默认 adjustPan 高度变化压缩布局,还有一种是 adjustResize 高度不变布局整体向上平移

看起来似乎很完美,但是 windowSoftInputMode 对于在 webview 中弹起的键盘似乎是无效的

经过一番百度之后发现这是 Android 的一个 Bug,只要 APP 对状态栏做了设置如状态色着色、浸式状态栏等,都会导致 windowSoftInputMode 对 webview 无效

由于在主题中设置了 windowTranslucentStatus,那就确实是这个导致的。但是经过测试,就算不使用全屏,不设置状态栏沉浸,甚至把主题调到了Theme.Holo.Light.DarkActionBar还是有上述问题

解决方案也很简单,使用一个神奇的 AndroidBug5497Workaround 类就好了。这个类实际上通过动态改变高度来实现系统的 adjustResize。所以 adjustPan 仍然是无效的

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

AndroidBug5497Workaround.assistActivity(this);

}

同时以防万一还是设置下 windowSoftInputMode

android:name=".MainActivity"

android:windowSoftInputMode="adjustResize">

跳出一个坑其实还有一个坑。由于在 html 中使用了 vh 作为高度单位,规定上 100vh 应该就等于设备的高度,在 IOS 中这个没问题,但是在 Android 中,100vh 等于的是 webview 的高度,这 TM 就调皮了

由于上面使用了 adjustResize 的方案,所以当键盘弹起时,webview 高度变化,100vh 对应的值也就发生变化了,导致页面被严重压扁

这个属于系统对 vh 的定义不同,原生代码没法适配了,只好设置 JS 去设置 viewport 去适配这个问题。原理很简单,在 viewport 强制设置 height 为固定值就可以了

const maxHeight = window.innerHeight

function fixedViewportHeight(fixed) {

let metaEl = document.querySelector('meta[name=viewport]')

let content = []

content.push('width=device-width')

fixed ? content.push('height=' + maxHeight) : ''

content.push('initial-scale=1.0')

content.push('user-scalable=no')

metaEl.setAttribute('content', content.join(','))

}

注意要开启 webview 对 viewport 的支持

WebSettings webSettings = this.getSettings();

webSettings.setJavaScriptEnabled(true);

webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);

webSettings.setJavaScriptCanOpenWindowsAutomatically(true);

webSettings.setSupportZoom(true); // 支持缩放

webSettings.setBuiltInZoomControls(true); // 设置内置的缩放控制 手势 + 缩放控件

webSettings.setDisplayZoomControls(false); // 不显示缩放控件

webSettings.setSaveFormData(false);

webSettings.setUseWideViewPort(true); // 支持html设置viewport

webSettings.setLoadWithOverviewMode(true); // body宽度超出自动缩放

webSettings.setDatabaseEnabled(true);

webSettings.setDomStorageEnabled(true);

webSettings.setGeolocationEnabled(true);

webSettings.setAppCacheEnabled(true);

webSettings.setAllowFileAccess(true); // 支持以 file:/// 打开本地文件,file:///android_asset 是默认被允许的

webSettings.setAllowFileAccessFromFileURLs(false); // 本地文件能否通过ajax访问别的本地文件

webSettings.setAllowUniversalAccessFromFileURLs(true); // 本地文件能否通过ajax跨域访问http/https

webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); // 允许https中加载http

注意:如果页面有 fixed 布局,为了保证 fix 布局在键盘弹起时不滚动,在键盘弹起前应该把 viewport 的 height 还原回去

总结

之前也适配了许多 android/ios 中关于 input 和 fixed 布局的问题,这次终于从系统层面上了解到了一些问题的原因

为什么 Android 对 fixed 布局支持的那么好

为什么在键盘弹起时 ios 的 fixed 布局无效

为什么 IOS 没有 resize 事件

参考

WPF (Windows Presentation Foundation) 的 WebView2 控件是一个用于在.NET 应用程序嵌入现代Web内容的强大工具。它基于Chromium浏览器内核,提供了一种全屏模式,可以更好地适应各种设备的屏幕大小。为了实现自适应屏幕,你可以采取以下步骤: 1. **布局管理**:使用`Grid`, `StackPanel` 或 `DockPanel` 等布局容器,并设置它们的`HorizontalAlignment` 和 `VerticalAlignment` 属性,以便在窗口大小变化时,控件能够自动调整其位置。 2. **SizeChanged Event**:注册`WebView2`的`SizeChanged`事件,当窗口尺寸改变时,响应这个事件并更新控件的大小和缩放比例。 3. **Responsive Design**:利用CSS媒体查询(Media Queries),在JavaScript或HTML编写针对不同视口宽度的样式规则,让网页内容能根据设备屏幕适配。 4. **Zooming and Scaling**:设置`WebView2`的`ZoomLevel`属性,允许用户手动缩放页面,或者通过编程动态设置缩放级别。 5. **硬件加速**:启用硬件加速,可以帮助提高渲染性能,并改善高分辨率或小屏幕设备上的用户体验。 ```xml <WebView2 x:Name="webView" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SizeChanged="webView_SizeChanged"> </WebView2> ``` 在XAML添加`SizeChanged`事件处理器示例: ```csharp private void webView_SizeChanged(object sender, SizeChangedEventArgs e) { webView.Width = e.NewSize.Width; webView.Height = e.NewSize.Height; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值