Android 放大KitKat WebView后不再回流文本

Android 放大KitKat WebView后不再回流文本,android,webview,android-webview,android-4.4-kitkat,zooming,Android,Webview,Android Webview,Android 4.4 Kitkat,Zooming,我有一个非常依赖网络视图的应用程序。 KitKat更新后,用户报告该应用程序在放大或缩小后不再回流文本。 我查看了文档,发现很多地方都发生了变化,但尽管其中谈到了缩放和缩放,但没有提到任何关于文本回流的内容。似乎一旦设置了视口,缩放就是一种平移和缩放操作,并且在缩放后不再有文本回流的选项。 有什么解决办法吗?KitKat Chromium网络视图不会回流文本。如果您担心文本易读性,请参阅中的“不再支持窄列和单列”部分,其中建议的解决方案是使用文本自动调整大小 如果你真的想恢复这种效果,那么你需要

我有一个非常依赖网络视图的应用程序。 KitKat更新后,用户报告该应用程序在放大或缩小后不再回流文本。 我查看了文档,发现很多地方都发生了变化,但尽管其中谈到了缩放和缩放,但没有提到任何关于文本回流的内容。似乎一旦设置了视口,缩放就是一种平移和缩放操作,并且在缩放后不再有文本回流的选项。
有什么解决办法吗?

KitKat Chromium网络视图不会回流文本。如果您担心文本易读性,请参阅中的“不再支持窄列和单列”部分,其中建议的解决方案是使用文本自动调整大小

如果你真的想恢复这种效果,那么你需要做如下事情:

  • 将所有内容放入
  • 按比例执行更改

    class MyWebViewClient extends WebViewClient {
        boolean scaleChangedRunnablePending = false;
    
        // Other code here
    
        @Override
        void onScaleChanged(final WebView webView, fload oldScale, float newScale) {
            if (scaleChangedRunnablePending) return;
            view.postDelayed(new Runnable() {
                @Override
                public void run() {
                    webView.evaluateJavaScript("recalculateWidth();", null);
                    scaleChangedRunnablePending = false;
                }
            }, 100);
        }
    }
    
    // Don't forget to webView.setWebViewClient(new MyWebViewClient());
    
  • 使用以下JavaScript

    function recalculateWidth() {
        $("#contentRoot").width(window.innerWidth);
    }
    
    或者,您也可以尝试修改视口元标记


  • 上面的内容应该在稍微延迟的情况下执行回流(这是为了将不必要的重新布局的数量降到最低)。

    谢谢大家,谢谢大家,这是一个很棒的线程!!我想加上我的2分。 不需要在HTML文件中添加id='contentRoot'的额外div。您可以使用body标记,它必须已经存在于任何html中。此外,正如EladAvron所写,JS代码可以直接从Java调用。总之,marcin.kosiba发布的原始答案适用于您无权修改的HTML

    对我有用的JS的调用是:

    webview.loadUrl("javascript:document.getElementsByTagName('body')[0].style.width=window.innerWidth+'px';");
    

    我不知道为什么,但添加“px”对我来说至关重要。

    感谢这些提示-结合它们,我发现以下解决方法不需要Java:

    var innerWidth = 0;
    var text_reflow = function () {
      if (window.innerWidth != innerWidth) {
        innerWidth = window.innerWidth;
        document.getElementsByTagName('body')[0].style.width = innerWidth+'px';
      }
    };
    text_reflow();
    setInterval(text_reflow, 500);
    
    不使用轮询间隔,例如,还可以

    window.onresize = text_reflow;
    addListener(window, 'touchstart', function (e) { text_reflow(); });
    

    不幸的是,似乎无法捕捉到实际的收缩到缩放事件。

    这是一个旧线程,但我只想添加我正在使用的解决方案,以防有人从中受益。我在某些页面上经历了一个奇怪的缩放问题,当页面一直向外缩放时,不幸的是,如果页面一直向外缩放,很难在JavaScript中检测到。解决方法是在调整页面大小之前检测缩放更改是否足够大

    以下解决方案适用于KitKat和棒棒糖,没有我在一些网站上看到的那种恼人的逐渐缩小功能

    class MyWebViewClient extends WebViewClient {
        private boolean mIsRunning = false;
        private float mZoomScale = 0.0f;
        private static final String REFLOW_TEXT = "javascript:document.getElementsByTagName('body')[0].style.width=window.innerWidth+'px';"
    
        @Override
        public void onScaleChanged(final WebView view, final float oldScale, final float newScale) {
            if (view.isShown() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                if (mIsRunning)    // Don't run if there's a resize runnable in the queue
                    return;
                if (Math.abs(mZoomScale - newScale) > 0.01f) {    // This stops the gradual zoom
                    mIsRunning = view.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            mZoomScale = newScale;
                            view.evaluateJavascript(REFLOW_TEXT, null);
                            mIsRunning = false;
                        }
                    }, 100);
                }
            }
        }
    }
    

    感谢marcin.kosiba和user3185518,我结合并修改了他们的解决方案来构建此答案。

    此代码将确保100%解决您的问题。 KitKat的问题 以罚款的形式出现 头

    
    java>
    view.evaluateJavascript(“document.getElementsByTagName('head')[0].appendChild('');”,null)

    webView.setWebViewClient(新的WebViewClient(){
    布尔scaleChangedRunnablePending=false;
    @凌驾
    尺度上的公共无效已更改(最终WebView视图、浮动旧尺度、浮动新尺度){
    super.onScaleChanged(视图、旧比例、新比例);
    if(scaleChangedRunnablePending)返回;
    view.postDelayed(新的Runnable(){
    @凌驾
    公开募捐{
    view.evaluateJavascript(“document.getElementsByTagName('head')[0].appendChild('');”,null);
    scaleChangedRunnablePending=false;
    }
    }, 100);
    }
    
    使用
    窗口的答案。Javascript中的innerWidth
    应该适用于Android 4.4(它使用Chrome 33进行网络视图),但在一些较新版本的Android上不起作用。这是因为Chrome 48和Chrome 61+在缩放时保持
    窗口。innerWidth
    不变(请参阅),这将影响所有Android 9设备和一些Android 5到8设备,具体取决于用户接受的Android系统WebView更新


    Chrome 61+上的替代品是提供
    window.visualViewport.width
    ,因此使用
    window.innerWidth
    的答案现在应该更新为使用
    (window.visualViewport!=未定义的?window.visualViewport.width:window.innerWidth)
    以获得最大的兼容性。

    @EladAvron我刚刚很快试用了它,对我来说效果很好
    document.getElementById('contentRoot')).style.width=window.innerWidth;
    就是我使用的JS,我直接从
    onScaleChanged
    调用了JS。也许可以使用DevTools查看是否调用了JavaScript?谢谢,我会再试一次,看看它是否有效。更糟糕的情况是,我得到了类似于
    viewport.setAttribute的东西('content','width=设备宽度,初始刻度='+newScale+'))
    基于您使用
    onScaelChanged
    的想法,我将尝试这两种方法,看看我能做些什么。好吧,您知道吗?它现在起作用了!不知道我之前做错了什么,但这显然是件愚蠢的事情。:-P另外,对任何考虑使用视口缩放的人来说,未来的提示-不要,因为那样它将同时进行缩放和缩放缩放视口使您获得一个超大且不可恢复的视口。除非您使用外部控件,否则,请发疯。好吧,我讨厌恢复此线程,但这会导致一个非常奇怪的问题。如果页面具有预设的缩放,然后旋转两次(即从横向到纵向和反向或反向),它将返回到默认的比例,然后在大约一分钟的时间内逐渐将自己缩小。这真的很奇怪。@EladAvron啊……这可能是由于一些舍入问题造成的。如果更改内容宽度导致更改比例,您将得到您描述的效果。最简单的修复方法是使用JavaScript而不是alt如果值
    window.innerWidth
    在内容宽度的5%以内,则输入内容宽度
    webView.setWebViewClient(new WebViewClient() {
                boolean scaleChangedRunnablePending = false;
                @Override
                public void onScaleChanged(final WebView view, float oldScale, float newScale) {
                    super.onScaleChanged(view, oldScale, newScale);
                    if (scaleChangedRunnablePending) return;
                    view.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            view.evaluateJavascript("document.getElementsByTagName('head')[0].appendChild('<meta name=\"viewport\" content=\"maximum-scale=0\">');", null);
                            scaleChangedRunnablePending = false;
                        }
                    }, 100);
                }