sirFunkenstine
sirFunkenstine

Reputation: 8515

SetSize WebView Android

I am having an issue with A webView not re-sizing. Im not exactly sure how to approach this problem. I have a webView with A custom webViewClient above a ListView in my application. The WebView has a dynamic accordion within it. When i click the accordion it expands, when i click it again it either expands again or retracts.

The problem i am having is that while the content retracts, the webView stays at its expanded size, resulting in a lot of white space at the bottom of my webView. Is there a way to call invalidate or setHeight in an ontouch method of the webView that does reload the webView? Or some override method in the webViewClient that can handle this?

Upvotes: 0

Views: 703

Answers (3)

hmartinezd
hmartinezd

Reputation: 1196

Actually there is a way. Use this before updating the content:

myWebView.loadUrl("about:blank");

Upvotes: 0

marcin.kosiba
marcin.kosiba

Reputation: 3231

I'm guessing you have height set to 'wrap_content'. The behavior you'r observing is because of a bug in the WebView and has been fixed in 4.4 (KitKat).

There is no good workaround for the bug - you could try temporarily forcing the WebView's height back to 0 every time the accordion is clicked but that will cause a glitch. Alternatively - if you control your content you could change the JavaScript that runs when the accordion is clicked to tell the WebView that it should shrink back to the previous height:

class MyWebView {
  private int previousHeight = -1;

  @Override
  public void onSizeChanged(int w, int h, int ow, int oh) {
    super.onSizeChanged(w, h, ow, oh);
    previousHeight = h;
  }

  public void accordionClicked() {
    // I'm assuming the accordion is a toggle, so if you click it once
    // it expands, you click it again - it shrinks.
    LayoutParams lp = getLayoutParams();
    if (lp.height == LayoutParams.WRAP_CONTENT)
     lp.height = previousHeight;
    else
     lp.height = LayoutParams.WRAP_CONTENT;
    setLayoutParams(lp);
  }
}

You would then need to use addJavaScriptInterface to expose a way for your JavaScript to call accordionClicked:

class JsInterface {
  private final WebView webView;
  public JsInterface(WebView webView) {
    this.webView = webView;
  }

  @JavascriptInterface
  public void onAccordionClicked() {
    webView.post(new Runnable() {
      @Override
      public void run() {
        webView.accordionClicked();
      }
    });
  }
}

You'd then register this interface in the same place you new up the WebView:

webView.addJavaScriptInterface("jsInterface", new JsInterface(webView);

Finally, call it in your JavaScript:

function accordionClicke() {
  ...
  jsInterface.onAccordionClicked();
}

If your accordion is more complicated you could calculate the height of your content in JavaScript and pass it back to the WebView:

  jsInterface.onAccordionClicked(document.body.clientHeight);

And then use that to set the right height:

  public void accordionClicked(int heightCss) {
    LayoutParams lp = getLayoutParams();
    lp.height = (int) (heightCss * getScale());
    setLayoutParams(lp);

Upvotes: 1

Evgeni Roitburg
Evgeni Roitburg

Reputation: 2097

use: android:descendantFocusability="blocksDescendants" on the wrapping layout this will prevent the webview from jumping to its start

use: webView.clearView(); mNewsContent.requestLayout(); every time you change the webview size to invalidate the layout, this will remove the empty spacing

for more info see:

Upvotes: 0

Related Questions