2012-12-27 34 views
6

Ứng dụng Android của tôi sử dụng WebView để hiển thị một loạt mã HTML mà tôi tạo 'khi đang di chuyển'. Mã HTML được tải bằng cách sử dụng mã sau:WebView chuyển sang neo bằng cách sử dụng 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); 

Tất cả đều hoạt động rất tốt. Lưu ý rằng tôi không tải một tệp HTML thực, tôi chỉ đang tạo một chuỗi đại diện cho một số HTML (hy vọng hợp lệ) và tải nó trong WebView.

Dù sao, HTML tôi tạo (phần trong phương thức 'getThreadBody') chứa các neo được đặt tên, ví dụ như thế này;

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

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

Bây giờ trong một số trường hợp tôi muốn WebView để di chuyển đến một trong những neo ngay sau khi tôi nạp HTML. Theo như tôi hiểu WebView hỗ trợ điều hướng (cuộn trong trường hợp này) để đặt tên neo, nhưng bắt là không ai nhấp vào bất kỳ siêu liên kết nào đến các neo đó, tôi muốn WebView cuộn khi được tải (không có vấn đề gì nếu có) là một sự chậm trễ ngắn giữa tải HTML và cuộn, quan điểm của tôi là nó không nên yêu cầu tương tác người dùng).

tôi tin rằng hành vi đó có thể đạt được bằng cách sử dụng phương pháp loadUrl của WebView và cung cấp một URL với các neo tại chỗ, ví dụ

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

Tuy nhiên, vì tôi không tiết kiệm HTML để bất kỳ tập tin tôi có thể không sử dụng phương pháp này ... Tất nhiên việc lưu HTML vào một tập tin tạm thời có thể là một giải pháp nhưng tôi muốn giữ nó như một phương sách cuối cùng, phải có một cách đơn giản hơn?

Tôi làm cách nào để đạt được điều này? Cảm ơn!


Resolved Dưới đây là đoạn code mà làm việc. Tôi tìm thấy một sự chậm trễ ngắn là cần thiết để cho tải trang trước khi thực hiện javascript nếu không nó là loại 50/50 cho dù nó đã làm việc hay không ...

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

Trả lời

6

Làm thế nào để kiểm soát nó bằng JavaScript? Tôi đã không thử nó nhưng có lẽ đây là một đầu mối.

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

Hãy nhớ bật javascript cho WebView.

---- bổ sung trả lời ----

tôi thấy rằng bạn sử dụng TimerTask để nạp javascript, đó làm việc nhưng tôi nghĩ rằng có một cách tốt hơn. WebView có một cuộc gọi lại tên là onPageFinished và nó sẽ được kích hoạt khi WebView kết thúc tải trang web. Bạn có thể tiêm JS của bạn ở đó.

webContents.setWebViewClient(new WebViewClient(){ 

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

}); 

Hy vọng điều này hữu ích!

+0

Tôi không biết điều đó là có thể, cảm ơn! –

+0

Chỉ một thông báo, khi sử dụng url này của chế độ xem web không thay đổi. webview.getUrl() trả về cùng một url được sử dụng để tải nội dung. – Codebeat

+0

Bạn cũng có thể sử dụng javascript để xử lý haschange bằng cách sử dụng sự kiện hashchange: $ j (cửa sổ) .bind ('hashchange', chức năng (e) {làm công cụ của bạn ở đây} – Codebeat

2

Trước hết, bạn không cần sử dụng javascript.Nếu bạn nạp nội dung với

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

bạn chỉ có thể di chuyển để neo với

webContents.loadUrl("some_dummy_url#anchor"); 

Thứ hai, thực hiện điều đó trên onPageFinished mà không kết quả kiểm soát bổ sung trong không bao giờ kết thúc vòng lặp! Khi loadUrl kết thúc onPageFinished get's được gọi một lần nữa và một lần nữa.

+1

điều này không hoạt động đối với tôi ... khi tôi chạy "webContents.loadUrl (" some_dummy_url # anchor ");" tôi nhận được một trang trống ... bất kỳ ý tưởng nào? – JannGabriel

+0

Tôi đã làm: .loadDataWithBaseURL ("app: html", ...) ;. Như anh ấy nói, chỉ một số URL giả. – 476rick

0

nếu bạn nạp html từ assets:

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

và bạn có thể di chuyển đến neo bên trong một trang web:

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

Nếu bạn có hành động bên ngoài (ví dụ: onclick event), hãy thử mã này

public static void scrollToAnchor(String id) { 
     sWebView.loadUrl("javascript:document.getElementById(\"" + id + "\").scrollIntoView()"); 
} 
Các vấn đề liên quan