WebView transitions to binding using loadDataWithBaseUrl

My Android application uses WebView to display a bunch of HTML code that I generate on the fly. HTML code is loaded using the following code:

StringBuilder builder = new StringBuilder(); // HTML builder.append("<html><head><link rel=\"stylesheet\" href=\"file:///android_asset/style.css\" type=\"text/css\">"); builder.append("</link></head><body>"); builder.append(getThreadBody()); builder.append("</body></html>"); webview.loadDataWithBaseURL("file:///android_asset/", builder.toString(), "text/html", "utf-8", null); 

All this works very well. Note that I am not loading the actual HTML file, I am just creating a line that represents some (hopefully valid) HTML and loading it into the WebView.

In any case, I generate HTML (the part in the getThreadBody method) contains named anchors, for example:

 <div> <a name="949823">Anchor 1</a> <div>All kinds of stuff</div> <a name="895984">Anchor 2</a> <div>...</div> </div> 

Now, in some cases, I want the WebView to move to one of these anchors as soon as I load the HTML. As far as I understand, WebView supports navigation (scrolling in this case) to named anchors, but the catch is that no one clicks hyperlinks on these bindings, I want the WebView to scroll when it is loaded (this is not a problem if there is slight delay between loading HTML and scrolling, I believe that this should not require user interaction).

I believe that the behavior can be achieved by using the loadUrl WebView method and serving the URL with the anchor in place, e.g.

 webview.loadUrl("file:///android_asset/page.html#895984", ...) 

However, since I do not save HTML in any file, I cannot use this method ... Of course, saving HTML to a temporary file may be a solution, but I would like to save this as a last resort, should there be an easier way?

How can i achieve this? Thanks!


Solved Here is the code that works. I found that a short delay is required to allow the page to load before javascript is executed, otherwise it would be 50/50 whether it worked or not ...

  StringBuilder builder = new StringBuilder(); // HTML builder.append("<html><head><link rel=\"stylesheet\" href=\"file:///android_asset/style.css\" type=\"text/css\">"); builder.append("</link>"); builder.append("<script>"); builder.append("function scrollAnchor(id) {"); builder.append("window.location.hash = id;}"); builder.append("</script>"); builder.append("</head><body>"); builder.append(getThreadBody()); builder.append("</body></html>"); webContents.loadDataWithBaseURL("file:///android_asset/", builder.toString(), "text/html", "utf-8", null); Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { String id = "895884"; webContents.loadUrl("javascript:scrollAnchor(" + id + ");"); } } }, 250); 
+6
source share
4 answers

How to manage it using JavaScript? I have not tried, but maybe this is the key.

 builder.append(getThreadBody()); builder.append("<script>window.location.hash="949823";</script>"); builder.append("</body></html>"); 

Remember to enable javascript for WebView.

---- Additional answer ----

I saw that you are using TimerTask to load javascript. This works, but I think there is another better way. WebView has a callback called onPageFinished, and it will be launched when WebView finishes loading the web page. You can enter your JS there.

 webContents.setWebViewClient(new WebViewClient(){ @Override public void onPageFinished(WebView view, String url) { String id = "895884"; webContents.loadUrl("javascript:scrollAnchor(" + id + ");"); } }); 

Hope this is helpful!

+6
source

First of all, you do not need to use javascript. If you have downloaded content using

 webContents.loadDataWithBaseURL("some_dummy_url",...); 

you can just scroll to snap using

 webContents.loadUrl("some_dummy_url#anchor"); 

Secondly, doing it on onPageFinished without additional control leads to an infinite loop! When loadUrl ends onPageFinished, is called again and again.

+2
source

if you download html from assets :

  webView.loadUrl("file:///android_asset/htmls/mypage.html#anchor"); 

and you can go to the anchor inside the web page:

 webView.loadUrl("http://www.stackoverflow.com/mypage.html#anchor"); 
0
source

If you have an external action (ex: onclick event ) try this code

  public static void scrollToAnchor(String id) { sWebView.loadUrl("javascript:document.getElementById(\"" + id + "\").scrollIntoView()"); } 
0
source

All Articles