WebView 顯示HTML富文字

numqin發表於2018-01-05

WebView 顯示HTML富文字

首先說明下富文字是什麼:富文字的定義是一種跨平臺的文字處理方式。

瀏覽大多數的論壇部落格,發現 android 顯示富文字的途徑主要有兩種:

  1. 將 Html 文字轉成 SpannableString ,通過 TextView 顯示。
  2. 利用 Webview 顯示 Html

Html 文字轉成 SpannableString

這裡簡單的提一下 Html 文字轉成 SpannableString ,這種方式主要是通過識別 html 的標籤,然後將內容轉成 SpannableString 。

android sdk 中有現成的方法可以使用 Html.fromhtml 不過它並不能識別所有的 Html 標籤。

如果自己處理 Html 標籤的太費時間,而且本人對 Html 並不是太熟,所以選擇第二種,使用Webview 顯示

使用 Webview 顯示 Html 文字

github

多說無益看效果:

WebView 顯示HTML富文字

如果你的 html 文字中使用到了網路上的圖片請先把網路請求許可權加上

  • 核心方法

    webView.loadData(htmlStr, "text/html", "UTF-8");
    webView.loadDataWithBaseURL(null, htmlStr, "text/html", "UTF-8", null);
    複製程式碼

    上面的 htmlStr 即你的 Html 文字字串

    實際使用中發現:webView.loadData() 這個方法中文顯示存在亂碼,使用webView.loadDataWithBaseURL() 時一切正常,暫時還不清楚裡面的原因。所以這裡主要介紹下 webView.loadDataWithBaseURL()方法

    public void loadDataWithBaseURL(
      String baseUrl, String data, String mimeType, String encoding, String historyUrl)
    複製程式碼
    • baseUrl —— 在 html 文字中一些的圖片的 src 地址可能是相對地址。像這樣

      https://upload.jianshu.io/users/upload_avatars/5382223/a.jpg
      如果 data 中圖片的地址是 /users/upload_avatars/5382223/a.jpg
      那麼你需要在 baseUrl 賦值 https://upload.jianshu.io
      複製程式碼
    • data —— html 文字

    • mimeType —— 文字型別

    • encoding —— 編碼格式

    • historyUrl —— 不知道

上手使用

  • 簡單的使用

    WebView webView = findViewById(R.id.web_view);
    //設定 webView
    webView.setScrollBarStyle(SCROLLBARS_OUTSIDE_OVERLAY);//取消滾動條
    webView.getSettings().setSupportZoom(false);//不支援縮放功能
    //載入 html 文字
    webView.loadDataWithBaseURL(null, htmlStr, "text/html", "UTF-8", null);
    複製程式碼
  • 圖片的處理

    當然這簡單的使用並不能滿足我們的需求,當圖片尺寸太大的時候還能橫滑,這怎麼行,

    //依賴的庫
    compile 'org.jsoup:jsoup:1.11.2'
    複製程式碼
    //這裡我們使用 jsoup 修改 img 的屬性:
    final Document doc = Jsoup.parse(htmltext);
    
    final Elements imgs = doc.getElementsByTag("img");
    for (int i = 0; i < imgs.size(); i++) {
       	//寬度填充手機,高度自適應
    	imgs.get(finalI).attr("style", "width: 100%; height: auto;");
    }
    複製程式碼
    //這裡我們使用 jsoup 修改 embed 的屬性:
    Elements embeds = doc.getElementsByTag("embed");
    for (Element element : embeds) {
        //寬度填充手機,高度自適應
        element.attr("width", "100%").attr("height", "auto");
    }
    
    //webview 無法正確識別 embed 為視訊,所以這裡把這個標籤改成 video 手機就可以識別了
    doc.select("embed").tagName("video");
    複製程式碼
  • 現在所有的圖片都是寬度跟手機一樣寬,高度自適應,像一些比較小的圖如果還跟螢幕一樣寬,這畫質不能忍啊,如果不滿意我們則需要再次處理。

    分兩種情況:

    1. 標籤中帶有圖片的寬高屬性
    2. 跟我一樣只有一個 src

    兩個的處理是一樣的,都需要知道圖片的寬高,通過對比圖片的寬度和手機的寬度

    if(圖片的寬度>手機的寬度){
    	//寬度填充手機,高度自適應
      	imgs.get(finalI).attr("style", "width: 100%; height: auto;");
    }else {
      	//不需要任何改動
    }
    複製程式碼

    第一種情況下我們可以通過 jsoup 來獲取定義的 width height

    第二種情況下由於只有 src ,我們需要獲取網路圖片的寬高,我這裡是直接通過 Glide 來獲取它的寬高,這裡的寬高是需要請求網路獲取的,所以我們可以在處理到最後一張圖片的時候通知,webview 去載入 Html 文字,而不是直接就載入。

    //依賴的庫
    compile 'com.github.bumptech.glide:glide:3.8.0'
    複製程式碼
    Glide.with(this)
       	.load(src)
       	.asBitmap()
       	.skipMemoryCache(true)
       	.diskCacheStrategy(DiskCacheStrategy.NONE)
       	.into(new SimpleTarget<Bitmap>() {
       		@Override
       		public void onResourceReady(
              Bitmap bitmap, GlideAnimation<? super Bitmap> glideAnimation) {
            	int width = bitmap.getWidth();
                int height = bitmap.getHeight();
                            }
        });
    複製程式碼
  • 使用 jsoup 處理完後,就不是載入原來的 htmlStr 而是 Jsoup 的 Document

    webView.loadDataWithBaseURL(null, doc.toString(), "text/html", "UTF-8", null);
    複製程式碼

相關文章