Android改变系统字体大小后造成webview里的页面布局打乱

最近在做APP里的页面时,偶然发现在Android下,使用rem做适配,
在改变系统字体大小后,会造成页面布局改变
在网上查询,大多的方案都是从APP里设置Webview的字体不根据系统字体变化而变化,
类似微信、支付宝等
测试其他的浏览器或者应用内置浏览器都发现调整系统字体大小后都不会出现问题
根本原因还是APP没有控制Webview的显示

解决方案

根本解决

从APP内根本解决,当然需要升级APP,重新发版本

曲线救国

在不升级APP的情况下,从页面的角度解决
具体的解决思路如下:

  1. 使用rem单位作为适配,所有的布局都已rem为单位
  2. 在dom节点加载之前,获取页面的宽度(即当前显示窗口宽度),具体代码如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //<head>
    ...
    var setSize = function() {
    var winWidth = document.documentElement.clientWidth;
    var size = (winWidth / 640 * 100);
    document.documentElement.style.fontSize = (size > 100 ? 100 : size) + 'px';
    }
    setSize();
    window.addEventListener('resize', function() {
    setTimeout(function() {
    setSize();
    }, 0);
    });
    ...
    //</head>

    640的值,根据设计给的UI的值或者按照自己设计的页面的宽度计算
    比如设计UI的宽度为640,则将html根节点的字体设置为 100px
    然后根据此比例,计算出每个布局的位置。比如设计宽100px,则将宽设置为1rem
    然后根据具体的视窗的大小,动态改变html根节点的字体大小,如在iphone5上,
    字体大小应该为50px,因为视窗宽度为320

  3. 设置body的宽度,以rem为单位的具体值,而不是百分比. 如6.4rem
  4. 因为Android调整系统字体后,html页面中的1px会根据系统字体放大或者缩小,实际显示0.8px或者1.2px,或其他数值
    而html元素都是根据html根节点的字体大小来缩放的,当字体大小变化时,body的宽度会超出文档的宽度
  5. 根据body的scrollWidth和视窗的宽度,算出对应的比例,再根据此比例,重置html根节点字体的大小
    需要在文档结构加载完后(能获取到body的正确宽度后)执行
    1
    2
    3
    4
    5
    6
    7
    8
    //使用jquery
    $(function() {
    if(document.body.clientWidth != document.documentElement.clientWidth)
    return;

    var rootFontSize = parseFloat(document.documentElement.style.fontSize);
    document.documentElement.style.fontSize = rootFontSize * document.documentElement.clientWidth / document.body.clientWidth + 'px';
    })

本文地址: http://gehaiqing.com/2016/11/21/js-rem-android-font-size/