的WebView跳使用loadDataWithBaseUrl锚WebView、loadDataWithBaseUrl

2023-09-06 16:34:31 作者:古城白衣少年殇

我的Andr​​oid应用程序使用的WebView显示一串HTML code,我产生'飞'。在HTML code使用下面的code加载:

StringBuilder的建设者=新的StringBuilder();     // HTML     builder.append(< HTML>< HEAD><链接相对= \样式\的href = \文件:///android_asset/style.css \型= \文/ CSS \> );     builder.append(< /链接>< /头><身体GT;);     builder.append(getThreadBody());     builder.append(< /身体GT;< / HTML>中);     webview.loadDataWithBaseURL(文件:/// android_asset /,builder.toString(),text / html的,UTF-8,NULL);

这所有的作品真的很好。请注意,我不加载实际的HTML文件,我只是创建重新presents一些(希望有效)的字符串的HTML并将其加载web视图。

不管怎么样,我的HTML生成(部分在'getThreadBody'方法)包含名为锚,例如像这样;

 < D​​IV>
    &其中;一个名字=949823>锚1所述; / a取代;
    < D​​IV>各种材料< / DIV>

    &其中;一个名字=895984>锚2'; / a取代;
    < D​​IV> ...< / DIV>
< / DIV>
 

现在在某些情况下,我想web视图导航到这些锚的一个,只要我加载HTML。据我了解的WebView支持导航(滚动在这种情况下)来命名锚,但美中不足的是,没有人点击这些锚的任何链接,我希望它被加载时的WebView滚动(它是,如果没有问题的存在为加载HTML和滚动之间的一个短暂的延迟,我的观点是,它不应该要求用户交互)。

我相信行为可以通过web视图的使用loadURL方法并提供与到位的锚,如:

一个URL来实现

webview.loadUrl(文件:///android_asset/page.html#895984,...) 做把锚式直跳袖剑 完

不过,由于我没有保存的HTML的任何文件,我不能用这个方法......当然保存HTML临时文件可能是一个解决方案,但我想保留,作为最后的手段,出现必须有一个更简单的方法?

我怎样才能做到这一点?谢谢!

解决 这里的code,它的工作原理。我发现了一个很短的延迟被要求让页面加载执行JavaScript的面前,否则它是一种50/50是否工作或不...

  StringBuilder的建设者=新的StringBuilder();

    // HTML
    builder.append(< HTML>< HEAD><链接相对= \样式\的href = \文件:///android_asset/style.css \型= \文/ CSS \> );
    builder.append(< /链接>);
    builder.append(&其中;脚本>中);
    builder.append(功能scrollAnchor(ID){);
    builder.append(window.location.hash = ID;});
    builder.append(&所述; /脚本>中);
    builder.append(< /头><身体GT;);
    builder.append(getThreadBody());
    builder.append(< /身体GT;< / HTML>中);

    webContents.loadDataWithBaseURL(文件:/// android_asset /,builder.toString(),text / html的,UTF-8,NULL);

    定时器定时=新的Timer();
    timer.schedule(新的TimerTask(){
        @覆盖
        公共无效的run(){
            字符串ID =895884;
            webContents.loadUrl(JavaScript的:scrollAnchor(+编号+););
        }
        }
    },250);
 

解决方案

如何用JavaScript的控制呢?我没有尝试,但也许这是一个线索。

  builder.append(getThreadBody());
builder.append(&其中;脚本> window.location.hash =949823;&所述; /脚本>中);
builder.append(< /身体GT;< / HTML>中);
 

记住启用JavaScript的web视图。

----其他答案----

我看到你使用的TimerTask加载JavaScript的,这工作,但我认为还有另一种更好的办法。的WebView有一个回调名为onPageFinished,这将是触发时的WebView完成加载网页。你可以注入你的JS那里。

  webContents.setWebViewClient(新WebViewClient(){

    @覆盖
    公共无效onPageFinished(web视图查看,字符串URL){
          字符串ID =895884;
          webContents.loadUrl(JavaScript的:scrollAnchor(+编号+););
    }

});
 

希望这是有用的!

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:

    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);

This all works really nice. Note that I'm not loading an actual HTML file, I'm merely creating a string that represents some (hopefully valid) HTML and load it in the WebView.

Anyway, the HTML I generate (the part in the 'getThreadBody' method) contains named anchors, for example like this;

<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 navigate to one of those anchors as soon as I load the HTML. As far as I understand the WebView supports navigating (scrolling in this case) to named anchors, but the catch is that nobody is clicking any hyperlinks to those anchors, I want the WebView to scroll when it is loaded (it is no problem if there is a short delay between loading the HTML and scrolling, my point is that it should not require user interaction).

I believe the behavior can be achieved by using the WebView's loadUrl method and supplying a URL with the anchor in place, eg

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

However, since I am not saving the HTML to any file I cannot use this method... Of course saving the HTML to a temporary file may be a solution but I'd like to keep that as a last resort, there must be a simpler way?

How can I achieve this? Thanks!

Resolved Here's the code that works. I found a short delay was required to let the page load before executing the javascript otherwise it was kind of 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);

解决方案

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!