How to resize a android webview after adding data in it

Viewed 60072

In a layout (linear, vertical) hierarchy I've got several views and one of them is a WebView. They all have same parameters:

android:layout_width="fill_parent"
android:layout_height="wrap_content"

For all views, the spacing between elements is correctly handled but for the Webview there is a lot of spaces after the displayed text inside.

I set the (HTML) text of the webview in the "onCreate" method of the activity using the layout.

Is there a way to let the webview resize itself, to match its content size?

By the way, the space left vary from one device to another (emulator vs Milestone vs Hero)

Any idea? Thanks

15 Answers

I had the same problem. I solved by changing the visibility of the WebView.

mWebView.setVisibility(View.GONE);
mWebView.loadData(".....");
mWebView.reload();
mWebView.setVisibility(View.VISIBLE);

I found:

(1) there are two height in webview. MeasureHeight and contentHeight. Note that the contentHeight is computed from the webcoreThread. The two height are not consistent any time!

(2) when layout finish.the webview reload content. The contentHeight is consistent with measureHeight.

So I think one solution is: make webview reload content after the layout finished.

My solution:

(1)extends webview . (2)override onlayout(),dispatchDraw(),

@Override
protected void dispatchDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.dispatchDraw(canvas);

    //mchanged  == is parameter in onlayout()
            //finished  == have run the code below !
    if (!mchanged && !finished) {
//                          
        String vHtml =".........." ;//your html content
        this.loadDataWithBaseURL("目录浏览", vHtml, "text/html", "utf-8",                             null);
            finished = true;
    }
}


     protected void onLayout(boolean changed, int l, int t, int r, int b) {
    // TODO Auto-generated method stub
    super.onLayout(changed, l, t, r, b);
    // tttttt
    if (!changed) { 
        this.mchanged = changed;//false
             }
        }

(3) webview need init before load every content.

public void intiFlag() {
    mchanged = true;
        finished = false ;
}

Hope this helps.

If you simply remove the view and then add a new one back, problem solved.

Here is an example:

WebView current_view = (WebView) view.getChildAt(i);
CharSequence current_text = current_view.getText();
int index = parent.indexOfChild(current_view);
parent.removeView(current_view);
current_view = new WebView(context);
parent.addView(current_view, index, layoutParams);
current_view.loadDataWithBaseURL( ...however you want... );
view.invalidate();

In summary... it just adds a new WebView just like the old right back to its parent at the same index.

It worked for me.

ViewTreeObserver viewTreeObserver = dataWebView.getViewTreeObserver();
        viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (dataWebView.getMeasuredHeight() > 0) {
                    dataWebView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    ((Activity) getContext()).runOnUiThread(() -> {
                        dataWebView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0));
                        dataWebView.setVisibility(View.GONE);
                        dataWebView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                        dataWebView.setVisibility(View.VISIBLE);

                    });
                }
            }
        });

After trying several ways, finally this worked for me: +++first use useState:

const [height, setHeight] = useState(0)

+++declare:

    const webViewScript = `
       setTimeout(function() { window.ReactNativeWebView.postMessage(document.documentElement.scrollHeight);}, 500);
    true;
  `

+++Next we wrap a View into the webview:

<View style={{ width: "100%", height: height }}>
      <WebView
        originWhitelist={["*"]}
        source={{ html: html }}
        onMessage={(event) => {
          setHeight(parseInt(event.nativeEvent.data))
        }}
        javaScriptEnabled={true}
        injectedJavaScript={webViewScript}/>
</View>
Related