2012-12-27 4 views
6

私のAndroidアプリはWebViewを使用して、「オンザフライで」生成する一連のHTMLコードを表示します。 HTMLコードは、次のコードを使用して読み込まれます。webViewがloadDataWithBaseUrlを使用してアンカーにジャンプ

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

これはすべてうまくいきます。私は実際のHTMLファイルをロードしていないことに注意してください。私は単純に(うまくいけば有効な)HTMLを表す文字列を作成し、それをWebViewにロードしています。

とにかく、私はHTML( 'getThreadBody'メソッドの部分)に名前付きアンカーを含んでいます。

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

    <a name="895984">Anchor 2</a> 
    <div>...</div> 
</div> 

は現在、いくつかのケースでは、私はWebViewのは、すぐに私はHTMLを読み込むと、それらのアンカーの一つにナビゲートします。 WebViewは名前付きアンカーへのナビゲート(この場合はスクロール)をサポートしていますが、そのアンカーへのハイパーリンクを誰もクリックしていないということは、WebViewがロードされたときにスクロールする必要がありますHTMLの読み込みとスクロールの間に短い遅延がありますが、私の主張はユーザーのやりとりを必要としないという点です)。

私は私が使用することはできません任意のファイルにHTMLを保存しておりませんので、行動は、しかし

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

例えば、WebViewののloadUrlメソッドを使用して適所にアンカーにURLを供給することによって達成することができると信じてこのメソッド...もちろん、HTMLを一時ファイルに保存することは解決策かもしれませんが、私は最後の手段として、よりシンプルな方法が必要であると考えていますか?

どうすればこの問題を解決できますか?ありがとう!解決済み


はここで動作するコードです。私には、JavaScriptによる制御、それをどのようにについて

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

...短い遅延が、それ以外の場合は、それが働いたかどうか50/50のようなものだったJavaScriptを実行する前に、ページの読み込みを許可する必要がありました見つかりましたか?私はそれを試していないが、おそらくこれは手掛かりです。

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

WebViewでJavaScriptを有効にすることを覚えておいてください。

----追加の回答----

私はあなたが動作しますが、私は別のより良い方法があると思いJavaScriptをロードするためにTimerTaskをを使用しているのを見ました。 WebViewにはonPageFinishedという名前のコールバックがあり、WebViewによるWebページのロードが完了するとトリガーになります。そこにあなたのJSを注入することができます。

webContents.setWebViewClient(new WebViewClient(){ 

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

}); 

希望すると便利です。

+0

私は可能でした、ありがとう! –

+0

これを使用すると、webviewのURLは変更されません。 webview.getUrl()は、コンテンツのロードに使用されたものと同じURLを返します。 – Codebeat

+0

また、ハッシュ変更イベントを使用してhaschangeを処理するためにjavascriptを使うこともできます:$ j(window).bind( 'hashchange'、function(e){ここにあなたのもの} – Codebeat

2

まず、javascriptを使用する必要はありません。あなたは

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

でコンテンツをロードした場合、あなたは単に決してループを終わることのないで追加の制御結果なしonPageFinishedにそれをやって、第二に

webContents.loadUrl("some_dummy_url#anchor"); 

に固定するためにスクロールすることができます! loadUrlが終了すると、PageFinishedのgetが何度も呼び出されます。

+1

これは私のためには機能しません... – JannGabriel

+0

私は:loadDataWithBaseURL( "app:html"、...);.彼が言うように、 "webContents.loadUrl(" some_dummy_url#anchor ");いくつかのダミーURL。 – 476rick

0

あなたはassetsからHTMLを読み込む場合:

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

とは、Webページ内のアンカーに移動することができます:あなたは、外部アクション(例:onclick event)をお持ちの場合

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

、このコードを試してください

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