Android webView字体突然变小的原因及解决
作者:程序员徐公 发布时间:2022-01-02 23:39:08
目录
背景
原因分析
setLoadWithOverviewMode
端内其他地方排查
总结
WebView 字体常见的其他坑
手机设置字体大小导致h5页面在webview中变形
Web js 网页解决方案
客户端 WebView 禁止缩放
小结
背景
最近,端内在做 webView 统一的时候,个性签名中的 WebView 替换为 CustomWebView 之后,发现字体突然变小。
一开始不知道是什么原因,通过二分法查找最近的提交,排查之后,发现是 SignatureWebView 的继承关系从 WebView 修改为 CustomWebView。revert 之后就正常了。
于是,我问自己,为什么会这样呢?
原因分析
我们知道,WebViewSetting 里面是可以修改 WebView 的一些默认设置的。
阅读官方文档,发现 setLoadWithOverviewMode,setUseWideViewPort 这两个方法看起来跟 WebView 缩放相关。
于是尝试把 setLoadWithOverviewMode 改为 false,很神奇,竟然正常了。
setLoadWithOverviewMode
这个方法的作用,简单来说,就是是否根据屏幕宽度自适应
Sets whether the WebView loads pages in overview mode, that is, zooms out the content to fit on screen by width. This setting is taken into account when the content width is greater than the width of the WebView control, for example, when getUseWideViewPort() is enabled. The default is false.
developer.android.com/reference/a…
这个问题解决之后,我心中又有这样的疑问,为什么别的地方没有问题,只有个性签名这里的 WebView 有问题。
带着这个疑问,我再次去浏览代码,发现个性签名里面 Webview 加载的网页,是自己拼接的 html。debug 之后,发现网页代码大概是这样的
<span style="word-wrap:break-word;font-family:system-ui;font-size:16px;color:#888888;">Https://www.baidu.com</span>
可以看到里面字体的单位是 px,跟 Android 的 dp px 有点像,是不是没作屏幕适配?
搜索发现 Web 网页的代码适配单位是 rem,有点类似于 dp。
Web 网页在适配分辨率的时候,通常会设置 viewport 属性
于是我尝试在代码里面加了这样的代码,发现 SignatureWebView 显示个性签名又正常了。
parsedHtml += "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover\">";
Web 网页字体的适配规则,这里就不班门弄斧了,有兴趣的可以自行搜索。
端内其他地方排查
我们知道,加载自定义 html,通常需要调用 loadDataWithBaseURL 方法,查看端内调用的地方,发现其他都是正常的。只有这个奇葩 SignatureWebView ,自己拼接的 html 没有加 viewport 属性,进行适配
总结
如果 html 是自己拼接的,并且像素是 px,不要设置 WebViewSetting 的 setLoadWithOverviewMode ,setUseWideViewPort(默认属性是 false),否则字体可能显示不正常,偏大或者偏小
如果 html 是自己拼接的,并且像素是 px,当我们设置 WebViewSetting 的 setLoadWithOverviewMode ,setUseWideViewPort 为 true(根据屏幕自适应),那么我们需要设置 html 的 viewport 规则,否则可能显示不正常
html 如果是自己拼接的,需要注意适配规则,像个人签名这种,用 webView 承载自己拼接的 html ,防止踩坑
WebView 字体常见的其他坑
手机设置字体大小导致h5页面在webview中变形
出现这个问题的原因是
默认浏览器中的内容是不受系统字体大小设置控制的,至少我遇到的几台手机都是这样的情况。
某些机型 WebView 字体的大小是受手机系统字体大小控制的
这个通常有两种解决方案。
Web js 网页解决方案
一般,我们动态计算好html的font-size之后,我们就啥都不干了,就走了。
但是,我们现在知道了,我们设置的大小不一定是真实的大小,所以,我们需要在设置完字体大小之后,再去重新获取一下html的font-size,看看实际的这个值,和我们设置的是不是一样。
如果不一样,就要根据比例再设置一次。
function htmlFontSize(){
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var width = w > h ? h : w;
width = width > 720 ? 720 : width
var fz = ~~(width*100000/36)/10000
document.getElementsByTagName("html")[0].style.cssText = 'font-size: ' + fz +"px";
var realfz = ~~(+window.getComputedStyle(document.getElementsByTagName("html")[0]).fontSize.replace('px','')*10000)/10000
if (fz !== realfz) {
document.getElementsByTagName("html")[0].style.cssText = 'font-size: ' + fz * (fz / realfz) +"px";
}
}
客户端 WebView 禁止缩放
Android WebView 是可以通过 WebSettings 禁止网页字体缩放的,可以通过 setTextZoom 方法解决
webview.getSettings().setTextZoom(100)
小结
这篇文章主要是记录 bug 的一个解决过程,技术含量不高,但是有一定的参考价值。尤其是 bug 的解决思路。
线上突然出现问题,一直找不出问题,尝试一下二分法,逐步缩小范围。
有时候,我们找到解决方案,却不一定知道原因是什么,这时候,可以多问一下自己,背后的原因是什么?在排查的过程中,我们会逐渐培养自己的一套问题解决思路,听起来很虚,但是确实存在的。
知道原因之后,我们可以继续再进一步排查一下,项目中其他模块是不是也存在这样的问题。
以后要怎么规避之类问题?写个 wiki 或者博客记录一下
来源:https://juejin.cn/post/6942404092819931166
猜你喜欢
- 本文实例讲述了Java类加载器和类加载机制。分享给大家供大家参考,具体如下:一 点睛1 类加载器负责将.class文件(可能在磁盘上,也可能
- 工厂接口定义/// <summary> /// 工厂接口定义 &nbs
- AppWidgetProvider 用来在HOME页面显示插件实现步骤:1、为AppWidget提供一个元布局文件AppWigdetProv
- Spring Boot 集成MyBatis在集成MyBatis前,我们先配置一个druid数据源。Spring Boot 集成druiddr
- 工厂模式定义:提供创建对象的接口。为何使用工厂模式工厂模式是我们最常用的模式了,著名的Jive论坛,就大量使用了工厂模式,工厂模式在Java
- 1、前言随着技术的发展,微信的一系列服务渗透进了我们的生活,但是我们应该怎样进行微信方面的开发呢。相信很多的小伙伴们都很渴望知道吧。这篇文章
- 前言本文主要讲述如何在同一个窗体内,实现不同功能模块的页面切换。一、准备工作1.搭建一个简单的mvvm项目结构首先搭建一个简单的项目框架,然
- 如下所示: @Override public String getEmployeeBysup(String employeeI
- 将网络资源url转化为File文件将互联网上的http开头的url资源,保存到本地。 private File getNetUrlHttp(
- 原始Spring开发Person.java准备Person.java类:package com.jektong.spring;public
- 昨天写了一篇Redis布隆过滤器相关的命令的文章,今天来说一说springboot中如何简单在代码中使用布隆过滤器吧。目前市面上也有好几种实
- 本文实例讲述了C#使用timer实现的简单闹钟程序。分享给大家供大家参考。具体如下:当我在电脑上工作,我经常会被一些东西吸引,比如某宝,结果
- 1、冒泡排序排序原理:相邻两个元素比较,如果前者比后者大,则交换两个元素。每执行一次,都会确定一个最大值,其位置就固定了,下一次就不需要再参
- Filter过滤器中访问getSession()要进行转化public void doFilter(ServletRequest reque
- 一、ArrayListArrayList是一个可以处理变长数组的类型,这里不局限于“数”组,ArrayList是一个泛型类,可以存放任意类型
- 本文介绍C# lock关键字,C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时
- 前言之前几篇我们介绍了贝塞尔曲线的原理、绘制曲线和动效实现,这些都是代码预设好的,如果我们要根据需要自行绘制曲线,就需要使用交互来实现了。本
- SEATA概要seata 是alibaba 出的一款分布式事务管理器,他有侵入性小,实现简单等特点。我们能够使用seata 实现分布式事务管
- 寻找到application.yml的读取的操作。从spring.factories 中查看到# Application Listeners
- 一、IO流的分类字符流ReaderInputStreamReader(节点流)BufferedReader(处理流)WriterOutput