如何根据内容动态收缩 WebView 大小?

Posted

技术标签:

【中文标题】如何根据内容动态收缩 WebView 大小?【英文标题】:How to Shrink WebView size dynamically according to its content? 【发布时间】:2013-03-10 21:32:09 【问题描述】:

问题的详细解释可以从this question了解,因为用户添加了图像以更好地解释它。

我正在我的 WebView 中加载 html 内容。我的布局有很多视图,WebView 放置在 ScrollView 内(根据布局要求)。请不要回答为 - "Don't put WebView inside ScrollView"。我知道将 WebView 放在 ScrollView 中并不是一件好事,但根据要求我需要这样做。

所以,我有左片段(显示列表项)和右片段(显示从左片段选择列表项时反映的数据)。现在,首先,当我在 WebV 中加载 Html 内容时,它显示正确。之后,当我用新的 Html 内容刷新 WebView 时,就会出现问题。

假设,我的第一个 Html 内容有 100 行,它正确显示,然后我用新的 40 行的 Html 内容重新加载 WebView,然后 WebView 没有缩小并适合 40 行的内容,它仍然保持为长达 100 行,在底部显示白色/空白区域。

因此,WebView 似乎能够从先前加载的较​​少内容重新调整自身大小,但在内容少于先前加载的内容时无法重新调整自身大小。

我尝试了很多方法,

在清单中添加android:hardwareAccelerated="true" This Blog 还有许多其他方式和博客 此外,我曾尝试使用mWebView.clearView();,这会导致重新调整 WebView 的大小,但有时 WebView 会开始闪烁,这很烦人。类似于this video

但是,找不到任何合适的解决方案。如果你们中的任何人之前有同样的问题,请告诉我我可以应用的最佳解决方案。

更新 -

在进一步谷歌搜索后,这似乎是 Honeycomb 中的一个众所周知的问题。 This question 也表示类似的问题。

【问题讨论】:

您一定尝试过,但我只是想确认一下,您是否尝试在 webView 上调用无效。另一件事是你是否将scrollView的fillViewPort属性设置为true。 @N-JOY 是的,我曾尝试调用 mWebView.invalidate() 并且我曾尝试将 fillViewPort 用于 ScrollView,但仍然没有成功。 【参考方案1】:

似乎没有办法在加载后动态调整 WebView(减小)其大小。所以,唯一能解决我的问题的就是重新加载完整的 WebView。

因此,我没有在 XML 中定义片段,而是通过每次动态添加片段来更改我的内容。通过它我能够解决我的问题。

【讨论】:

“重新加载完整的 webview”是什么意思? @Bryan 这意味着我正在将整个片段替换为另一个片段。【参考方案2】:

这是WebView 的一个已知问题,并且某些可用的解决方案不适用于所有设备。

我尝试了 SO 答案中给出的许多解决方案,并在互联网上进行了搜索,但没有一个对我有用。

我结束了,删除 WebView 并在 Layout 中的相同位置再次添加 WebView

这是演示代码,

        final RelativeLayout rl = new RelativeLayout(this);
        myWebView = new WebView(this);
        myWebView.setBackgroundColor(Color.GRAY);
        myWebView.loadUrl("file:///android_asset/1.htm");
        rl.addView(myWebView);  // ******* Added At Index 0
        Button btn = new Button(this);
        btn.setOnClickListener(new OnClickListener() 
            public void onClick(View v) 
                if (!flg) 
                    rl.removeViewAt(0);
                    myWebView = new WebView(MainActivity.this);
                    myWebView.setBackgroundColor(Color.GRAY);
                    myWebView.loadUrl("file:///android_asset/3.htm");
                    rl.addView(myWebView, 0, new RelativeLayout.LayoutParams(
                            new LayoutParams(LayoutParams.FILL_PARENT,
                                    LayoutParams.WRAP_CONTENT)));
                    flg = true;
                 else 
                    rl.removeViewAt(0);
                    myWebView = new WebView(MainActivity.this);
                    myWebView.setBackgroundColor(Color.GRAY);
                    myWebView.loadUrl("file:///android_asset/1.htm");
                    rl.addView(myWebView, 0, new RelativeLayout.LayoutParams(
                            new LayoutParams(LayoutParams.FILL_PARENT,
                                    LayoutParams.WRAP_CONTENT)));
                    flg = false;
                
            
        );
        rl.addView(btn); // ******* Added At Index 1
        setContentView(rl);

【讨论】:

谢谢你的回复,但是你有没有检查我在问题中添加的this blog,它清楚地表明如果我们每次尝试动态添加WebView都会出现WebView的闪烁效果。 这在我的情况下有效,所谓的“眨眼”几乎是不可见的。【参考方案3】:

伙计们,我似乎找到了本地内容的解决方案。您应该在加载新内容之前调用 webView.reload() - 它以某种方式调整大小而不会闪烁。

【讨论】:

我也尝试过重新加载方法,但我也没有找到任何运气。 ':( 疯了,但这实际上适用于本地内容!偶尔会失败,但总的来说到目前为止看起来是一个非常好的解决方案【参考方案4】:

这里我根据软键盘显示改变了 webview 的高度

  activityRootView = (RelativeLayout) findViewById(R.id.webview1);
            mWebView = (WebViewEx) WebViewActivity.this.findViewById(R.id.webview);

            activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new    OnGlobalLayoutListener() 
                public void onGlobalLayout() 
                    Rect r = new Rect();
                    //r will be populated with the coordinates of your view that area  still visible.
                    activityRootView.getWindowVisibleDisplayFrame(r);

                    int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
                    if(heightDiff != lastValue) 
                        if (heightDiff > 100)  // if more than 100 pixels, its probably a keyboard...
                            Log.i("Screen Size Changed","KeyBoard Displaying"+ r.bottom);

                            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
                             params.height=r.bottom;
                             mWebView.setLayoutParams(params);
                            //appView.sendjavascript("onKeyBoardShow(" + r.bottom + ");");
                         else 
                           /// appView.sendJavascript("onKeyBoardHide();");
                            Log.i("Screen Size Changed","KeyBoard not displaying" +r.bottom);
                            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
                             params.height=r.bottom;
                             mWebView.setLayoutParams(params);
                        
                        lastValue = heightDiff;
                    
                 
            );

【讨论】:

我在使用软键盘时完全没有任何问题,所以这与我的问题没有任何联系【参考方案5】:

我还没有尝试过,但您为什么不尝试在加载新内容之前再次设置 weblayout 参数。即设置高度和宽度来包装内容。如果发现成功请回复。如果找不到成功,最好选择 javascipt

【讨论】:

【参考方案6】:

我将 WebView 的可见性设置为 Gone,并在 WebView 消失时将内容加载到 WebView 中。然后我在让 DOM 和 JS 加载后将可见性设置为可见,它似乎正确地绘制了长度。由于没有像 onPageFinished 这样的回调来确定 JS 何时完成执行,所以在将可见性设置为 true 之前,我给 WebView 延迟了一秒。此解决方法足以满足我的目的,因此希望它能满足你们中的一些人的需求!

【讨论】:

【参考方案7】:

每次创建 webview 对象并为其提供参数都是一件痛苦的事情,相反,您可以执行以下步骤,它会起作用

assets文件夹中放一个空白的html文件并给它一个名字 empty.html

致电webview.loadUrl("file:///android_asset/empty.html");

现在加载您的内容。

Webview 会缩小它的高度。

确保您没有在empty.html中放任何内容

【讨论】:

不,它对我不起作用。我猜所有这些技巧有时会在某些具有不同固件的设备中起作用,但它们并不是对所有设备都 100% 确定的。【参考方案8】:

This 施展魔法!它说

Android 属性:android:layout_weight = "布局中的 1 应该可以工作...

在我的例子中,WebView 在RelativeLayout 中。所以这样做 android:layout_ 就像一个魅力:)

【讨论】:

也适合我。似乎是最简单的解决方案。我的 WebView 是 LinearLayout 的子视图,它的 layout_height 设置为“0dp”。 请提供您的布局。我的 WebView 总是得到 0 高度。 @AlpAltunel 请阅读更多“在我的情况下,WebView 在 RelativeLayout。所以这样做 android:layout_ 就像一个魅力:)”【参考方案9】:

正如@Ankit 指出的那样,转到一个空白页面可能会有所帮助。不过,“about:blank”更好。

【讨论】:

以上是关于如何根据内容动态收缩 WebView 大小?的主要内容,如果未能解决你的问题,请参考以下文章

根据 iPhone 上的内容设置 webview 的动态高度

如何根据底部的 webview 设置 Viewcontroller 动态高度?

如何确定 WKWebView 的内容大小?

如何确定 WKWebView 的内容大小?

如何根据自动收缩的标签为多个标签设置相同的字体比例?

表视图内的 UITextView 未根据内容调整大小