My Android app uses a WebView to display a bunch of HTML code that I generate \'on the fly\'. The HTML code is loaded using the following code:
First of all, you don't need to use javascript. If you loaded content with
webContents.loadDataWithBaseURL("some://dummy/url",...);
you can simply scroll to anchor with
webContents.loadUrl("some://dummy/url#anchor");
Secondly, doing that on onPageFinished without additional control results in never ending loop! When loadUrl finishes onPageFinished get's called again and again.
How about control it by JavaScript? I didn't try it but maybe this is a clue.
builder.append(getThreadBody());
builder.append("<script>window.location.hash="949823";</script>");
builder.append("</body></html>");
Remember enable javascript for WebView.
----Additional Answer----
I saw that you use TimerTask to load the javascript, That works but I think there is another better way. WebView have a callback named onPageFinished and it will be trigger when WebView finish loading webpage. You could inject 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 useful!
if you load the html from the assets
:
webView.loadUrl("file:///android_asset/htmls/mypage.html#anchor");
and you can move to the anchor inside a web page:
webView.loadUrl("http://www.stackoverflow.com/mypage.html#anchor");
If you have external action (eg: onclick event
), try this code
public static void scrollToAnchor(String id) {
sWebView.loadUrl("javascript:document.getElementById(\"" + id + "\").scrollIntoView()");
}
If you have in your layout the webview inside a nestedScrollView the nesting will prevent the scrolling events from working properly. Once you take it out it will work without any need to reload or add javascript.
Additionally if you want to keep the nestedScrollView and dont care if the user cannot scroll past that section you can add fillViewPort=true
to the nestedScrollView and android:layout_height="wrap_content"
to the webview.
It would look something like:
<androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.appbar.AppBarLayout>
...
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewPort=true
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<WebView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>