1. 程式人生 > >Android 顯示富文字

Android 顯示富文字

一、TextView 顯示

關於 TextView 顯示富文字資訊,使用 Html.fromHtml() 得到 CharSequence 物件,然後賦值給 TextView 完成顯示; Html.fromHtml() 有兩個常用的過載方法:
1. fromHtml(String source)
2. fromHtml(String source, ImageGetter imageGetter, TagHandler tagHandler)
區別在於第一個用來顯示文字的,第二個還可以顯示圖片;方法一直接呼叫即可,沒什麼好說的,方法二由於要建立 ImageGetter 顯示圖片,並且載入網路圖片需要子執行緒中處理,所以相關程式碼如下:

在子執行緒中建立 ImageGetter, 並呼叫 fromHtml(String source, ImageGetter imageGetter, TagHandler tagHandler) 方法得到 CharSequence 物件,通過 Handler 回到主執行緒,為 TextView 設定富文字

new Thread(() -> {
            Html.ImageGetter imageGetter = source -> {
                Drawable drawable = getImageFromNetwork(source);
                if
(drawable != null) { drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); } return drawable; }; CharSequence charSequence = Html.fromHtml(htmlCode, imageGetter, null); Message message = mHandler.obtainMessage(); message.what = 0
; message.obj = charSequence; mHandler.sendMessage(message); })
.start();
    public Drawable getImageFromNetwork(String imageUrl) {
        Drawable drawable;
        try {
            URL myFileUrl = new URL(imageUrl);
            HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
            conn.setDoInput(true);
            conn.connect();
            InputStream is = conn.getInputStream();
            drawable = Drawable.createFromStream(is, null);
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return drawable;
    }

    private static class MyHandler extends Handler {

        WeakReference<Activity> weakReference;

        MyHandler(Activity activity) {
            weakReference = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 0) {
                weakReference.get().txtView.setText((CharSequence) msg.obj);
                weakReference.get().txtView.setClickable(true);
                weakReference.get().txtView.setMovementMethod(LinkMovementMethod.getInstance());
            }
        }
    }

但是,一執行,GG… 文字的顯示樣式完全沒變化, Html 裡面明明設定了一些 style 屬性;無奈,祭出 WebView 載入富文字;

二、WebView 顯示富文字

關於 WebView、可以載入網頁、本地 html 檔案、竟然還可以載入 html 程式碼;6得飛起
1. 對 WebView 進行一些基礎設定

        WebSettings webSettings = webView.getSettings();
        webSettings.setDisplayZoomControls(false); //隱藏webview縮放按鈕
        webSettings.setJavaScriptEnabled(true);//支援js
//        webSettings.setBuiltInZoomControls(true); // 顯示放大縮小
//        webSettings.setSupportZoom(true); // 可以縮放
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                // 得到 URL 可以傳給應用中的某個 WebView 頁面載入顯示
                return true;
            }
        });
  1. 載入 Html 程式碼
webView.loadDataWithBaseURL(null, HtmlCode, "text/html", "UTF-8", null);
  1. 注意,載入HTML不要使用 loadData(HtmlCode, “text/html”, “UTF-8”); 會有亂碼問題;執行除錯,FaKe,圖片太寬,文字太小;所以需要將內容壓縮在螢幕寬度內;新增程式碼:
        webSettings.setUseWideViewPort(true);
        webSettings.setLoadWithOverviewMode(true);
  1. 執行,發現圖片完全顯示在了螢幕內,但是文字還是沒什麼變化,太小;最後找到方法,利用 Jsoup 顯示 WebView,去掉第三步的程式碼,將第二步改為
webView.loadDataWithBaseURL(null, HtmlFormat.getNewContent(htmlCode), "text/html", "UTF-8", null);
  1. HtmlFormat 如下:需要匯入 Jsoup 依賴(compile ‘org.jsoup:jsoup:1.9.2’)
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.Jsoup;
import org.jsoup.select.Elements;

public class HtmlFormat {
     public static String getNewContent(String htmltext) {
         Document doc = Jsoup.parse(htmltext);
         Elements elements = doc.getElementsByTag("img");
         for (Element element : elements) {
             element.attr("width", "100%").attr("height", "auto");
         }
         return doc.toString();
     }
 }