1. 程式人生 > >android TextView 載入html 顯示圖片並且新增img標籤點選事件工具類 富文字 圖文混排 圖片大小調整

android TextView 載入html 顯示圖片並且新增img標籤點選事件工具類 富文字 圖文混排 圖片大小調整

注意,本人部落格主要是為了自己記錄,如果有問題歡迎反饋哈。

android的TextView可以載入html程式碼,並且識別他們的標籤,用的方法就是setText(Html.fromHtml(source)),其中source是指定的字串,包含html標籤,用setText(Html.fromhtml(source))可以識別html標籤(本人經常用其去除編輯遺漏的空格回車等標籤),但是這種簡單的做法並不能將其中的圖片加載出來,其實圖片也可以載入並且可以新增圖片點選事件,如圖片點選放大功能,效果圖如下。

直接上工具類具體程式碼,其中有很多註釋,寫的很清楚,有不明白的或者有問題的歡迎評論。

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.Html;
import android.text.Html.TagHandler;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.ImageSpan;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import org.xml.sax.XMLReader;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Locale;

/**
 * 將html設定到textview中的工具類
 * textview有方法 setText(Html.fromHtml(source)),其中source是指定的字串,包含html標籤,用setText(Html.fromhtml(source))可以去除其中的標籤,實際上是識別標籤,但是這種簡單的做法
 * 並不能將其中的圖片加載出來
 * 此工具類可以將html程式碼中的img標籤識別並進行圖片資源請求
 * 同時可以將img標籤進行處理 新增上點選事件
 */
public class HtmlFromUtils {

    /**
     * 網路請求獲取圖片
     */
    private static Drawable getImageFromNetwork(String imageUrl) {
        URL myFileUrl = null;
        Drawable drawable = null;
        try {
            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 Drawable drawable;

    /**
     * 將html字串中的圖片加載出來 設定點選事件 然後TextView進行顯示
     *
     * @param context
     * @param v
     * @param sources
     */
    public static void setTextFromHtml(final Activity context, final TextView v, final String sources) {
        if (TextUtils.isEmpty(sources) || context == null || v == null)
            return;
        synchronized (HtmlFromUtils.class) {//同步鎖
            v.setMovementMethod(LinkMovementMethod.getInstance());//如果想對img標籤新增點選事件必須呼叫這句 使圖片可以獲取焦點
            v.setText(Html.fromHtml(sources));//預設不處理圖片先這樣簡單設定
            new Thread(new Runnable() {//開啟執行緒載入其中的圖片
                @Override
                public void run() {
                    Html.ImageGetter imageGetter = new Html.ImageGetter() {//Html.fromhtml方法中有一個引數 就是ImageGetter 此類負責載入source中的圖片


                        @Override
                        public Drawable getDrawable(String source) {
                            source = "http://www.dujiaoshou.com/" + source;//source就是img標籤中src屬性值,相對路徑的此處可以對其進行處理新增頭部
                            drawable = getImageFromNetwork(source);
                            if (drawable != null) {

                                int w = drawable.getIntrinsicWidth();
                                int h = drawable.getIntrinsicHeight();
                                //對圖片大小進行等比例放大 此處寬高可自行調整
                                if (w < h && h > 0) {
                                    float scale = (400.0f / h);
                                    w = (int) (scale * w);
                                    h = (int) (scale * h);
                                } else if (w > h && w > 0) {
                                    float scale = (1000.0f / w);
                                    w = (int) (scale * w);
                                    h = (int) (scale * h);
                                }

                                drawable.setBounds(0, 0, w, h);
                            } else if (drawable == null) {
                                //bindData();
                                return null;
                            }
                            return drawable;
                        }
                    };
                    //第三個引數 new URLTagHandler(context)負責新增img標籤的點選事件
                    final CharSequence charSequence = Html.fromHtml(sources, imageGetter, new URLTagHandler(context));
                    //在activiy的runOnUiThread方法中更新ui
                    context.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            v.setText(charSequence);
                        }
                    });


                }
            }).start();
        }

    }


    /**
     * 此類負責處理source字串中的img標籤 對其新增點選事件
     */
    private static class URLTagHandler implements TagHandler {

        private Context mContext;

        public URLTagHandler(Context context) {
            mContext = context.getApplicationContext();
        }

        @Override
        public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
            // 處理標籤<img>
            if (tag.toLowerCase(Locale.getDefault()).equals("img")) {
                // 獲取長度
                int len = output.length();
                // 獲取圖片地址
                ImageSpan[] images = output.getSpans(len - 1, len, ImageSpan.class);
                String imgURL = images[0].getSource();
                // 使圖片可點選並監聽點選事件
                output.setSpan(new URLTagHandler.ClickableImage(mContext, imgURL), len - 1, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }

        private class ClickableImage extends ClickableSpan {
            private String url;
            private Context context;

            public ClickableImage(Context context, String url) {
                this.context = context;
                this.url = url;
            }

            @Override
            public void onClick(View widget) {
                // 進行圖片點選之後的處理
                Toast.makeText(context, "點選圖片的地址" + url, Toast.LENGTH_LONG).show();
            }
        }
    }
}