11

I've created a small Activity which is capable of loading two different HTML strings in a webview. When I run the Activity it starts by loading the String from the page_1 variable. So far so good. The page shows as expected. I've added an onFling listener which should make the activity load the content of the page_2 variable. The problem is that even though the onFling is called and the loadUrl is called the webview isn't updated?

My activity looks like this:

import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.webkit.WebView;

public class Test extends Activity {
private GestureDetector mGestureDetector;
private WebView mWebView;
private int mPageIndex;

private static final String page_1 = "<html><body>Hello page 1</body></html>";
private static final String page_2 = "<html><body>Hello page 2</body></html>";

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.test);
  mWebView = (WebView) findViewById(R.id.webview);
  mWebView.loadData(page_1, "text/html", "utf-8");
  setupGestureDetection();
  mPageIndex = 0;
}

private void setupGestureDetection() {
  mGestureDetector = new GestureDetector(new MyGestureDetector());
  mWebView.setOnTouchListener(new OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
      return mGestureDetector.onTouchEvent(event);
    }
  });
}

class MyGestureDetector extends GestureDetector.SimpleOnGestureListener {
  private static final int SWIPE_DISTANCE_THRESHOLD = 120;
  private static final int SWIPE_VELOCITY_THRESHOLD = 200;

  private boolean isHorizontalSwipe(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    if (Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
      if (Math.abs(e1.getX() - e2.getX()) > SWIPE_DISTANCE_THRESHOLD) {
        return true;
      }
    }
    return false;
}

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
  if (isHorizontalSwipe(e1, e2, velocityX, velocityY)) {
    if (e1.getX() > e2.getX()) {
      // Right to left
      if (++mPageIndex % 2 == 0) {
        mWebView.loadData(page_1, "text/html", "utf-8");
      } else {
        mWebView.loadData(page_2, "text/html", "utf-8");
      }
      return true;
    }
  }
  return false;
}
}
}

My layout looks like this:

<?xml version="1.0" encoding="utf-8"?>
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/webview"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent" />

I hope someone can help me! :-)

Best regards

Stig Andersen

Stig Andersen
  • 113
  • 1
  • 5
  • You can get error output from the web console if you add a [WebChromeClient](http://developer.android.com/reference/android/webkit/WebChromeClient.html). `mWebView.setWebChromeClient(new WebChromeClient());` should do it. – dokkaebi Jan 25 '12 at 09:08
  • Also, how do you know the loadData calls are being made? Are you stepping through with the debugger? Printing Log messages? – dokkaebi Jan 25 '12 at 09:10

3 Answers3

10

First, try to avoid WebView#loadData(String, String, String) like the plague - it's a buggy p.o.s. Use WebView#loadDataWithBaseURL(String, String, String, String, String) instead.

Further, this will fix your problem. Counter-intuitive I know, but hey, it's the Android way.

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        if (isHorizontalSwipe(e1, e2, velocityX, velocityY)) {
            if (e1.getX() > e2.getX()) {
                // Right to left
                if (++mPageIndex % 2 == 0) {
                    mWebView.loadDataWithBaseURL(null, page_1, null, "utf-8", null);
                } else {
                    mWebView.loadDataWithBaseURL(null, page_2, null, "utf-8", null);
                }
                // Seriously. You must return false for the loadDataWithBaseURL to work. Not kidding. So you could skip this return.
                return false;
            }
        }
        return false;
    }
Jens
  • 16,853
  • 4
  • 55
  • 52
  • Hi Jens, You're my hero! Thanks for helping my out! :-) – Stig Andersen Jan 25 '12 at 10:09
  • 1
    @Jens: Hi,I have got the same problem as Sting Andersen and tried your solution.But still,problem is there for not loading of content 2nd time? can you tell me,what else can be the solution other than this? – Hiral Vadodaria Aug 27 '12 at 13:44
4

These solutions didn't work for me. what eventually worked is clearing the cache and history before loading the data (loadData worked in this case):

webView.clearCache(true);
webView.clearHistory();
webView.loadData(html, "text/html", "UTF-8");

Hope this will help.

Yoel Gluschnaider
  • 1,785
  • 1
  • 16
  • 20
  • webView.loadDataWithBaseURL(null, html, null, "utf-8", null); – Abu Sadat Mohammed Yasin Mar 09 '13 at 07:26
  • Clearing cache and history is needed on certain OS levels (e.g. 4.1.1, but not 4.4.2) whenever a web view is reloaded with either load method. Even for a brand new web view - the underlying implementation appears to hold onto "old" content and uses the same URL (null in my case) to key to old content that no longer exists and hey presto an empty display. Two days, this just saved me after two days of banging my head against a wall with different devices having different behavior. Now to subclass my own web view so as not to forget about this again. – Colin Feb 17 '15 at 19:44
4

Those who are still having the issue i found a quick solution just use a handler for this

Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        webView.loadDataWithBaseURL("", html, "text/html", "UTF-8", null);
    }
}, 10) ;
FK Khan
  • 116
  • 4
  • Thank you for this comment! It was driving me crazy :) Solution in Kotlin: val handler = Handler() handler.postDelayed(Runnable { myWebview.loadUrl("example.com") }, 10). All other solution failed (clearing cache, destory(),...), for me only your solution works! Similar problem here: https://stackoverflow.com/questions/55399418/android-webview-not-loading-url-for-second-time – ThomasV Oct 27 '21 at 15:10