8

私のAndroidアプリは、WebViewを使用して、「オンザフライ」で生成した一連のHTMLコードを表示します。HTMLコードは、次のコードを使用してロードされます。

    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>

場合によっては、HTMLをロードするとすぐにWebViewがこれらのアンカーの1つに移動するようにしたいことがあります。WebViewが名前付きアンカーへのナビゲート(この場合はスクロール)をサポートしていることを理解している限り、キャッチは、誰もそれらのアンカーへのハイパーリンクをクリックしていないということです。WebViewがロードされたときにスクロールする必要があります(そこにある場合は問題ありません) HTMLの読み込みとスクロールの間の短い遅延です。私のポイントは、ユーザーの操作を必要としないことです)。

この動作は、WebViewのloadUrlメソッドを使用し、アンカーが配置されたURLを提供することで実現できると思います。

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

ただし、HTMLをどのファイルにも保存していないため、この方法は使用できません...もちろん、HTMLを一時ファイルに保存することも解決策かもしれませんが、最後の手段としてそれを維持したいので、もっと簡単な方法?

どうすればこれを達成できますか?ありがとう!


解決済み これが機能するコードです。javascriptを実行する前にページをロードするために短い遅延が必要であることがわかりました。そうでない場合は、機能するかどうかにかかわらず、50/50のようなものでした...

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

5 に答える 5

6

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 + ");");
    }

});

これがお役に立てば幸いです。

于 2012-12-28T02:54:12.893 に答える
6

まず第一に、javascriptを使用する必要はありません。コンテンツをロードした場合

webContents.loadDataWithBaseURL("some://dummy/url",...);

スクロールして固定するだけです

webContents.loadUrl("some://dummy/url#anchor");

次に、追加の制御なしでonPageFinishedでこれを行うと、ループが終了することはありません。loadUrlがonPageFinishedを終了すると、getが何度も呼び出されます。

于 2013-12-04T10:42:27.280 に答える
1

外部アクション(例:)がある場合はonclick event、このコードを試してください

 public static void scrollToAnchor(String id) {
        sWebView.loadUrl("javascript:document.getElementById(\"" + id + "\").scrollIntoView()");
 }
于 2017-12-17T10:24:16.813 に答える
1

レイアウトにnestedScrollView内のWebビューがある場合、ネストするとスクロールイベントが正しく機能しなくなります。一度取り出すと、JavaScriptをリロードしたり追加したりしなくても機能します。

さらに、nestedScrollViewを保持し、ユーザーがそのセクションを超えてスクロールできない場合でも気にしない場合はfillViewPort=true、nestedScrollViewとWebビューに追加できますandroid:layout_height="wrap_content"

次のようになります。

<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>
于 2020-04-06T16:14:11.693 に答える
0

assets:からhtmlをロードする場合

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

Webページ内のアンカーに移動できます。

webView.loadUrl("http://www.stackoverflow.com/mypage.html#anchor");
于 2015-09-17T20:35:04.153 に答える