android 中使用ImageGetter在TextView中顯示網(wǎng)絡(luò)圖片

今天在做項(xiàng)目的時(shí)候籽御,接口返回的信息是html格式的绰沥,一開始我是用textView.setText(Html.fromHtml("html標(biāo)簽字符串",null,null));但是發(fā)現(xiàn)html標(biāo)簽里有img標(biāo)簽篱蝇,里面還有一個(gè)圖片的鏈接url,如下所示:
<img title="058B4D41236B9980FC1C07C9EC49872E.png" src="http://www.hbxyjob.cn/cmsfiles/1/image/public/201708/20170824093509_2avfad9vwc.png"/>
尼瑪零截,這怎么顯示呢秃臣?于是在網(wǎng)上找了很久資料涧衙,改了一下代碼哪工,實(shí)現(xiàn)的效果如下:

HtmlGetter.gif
1雁比、思路分析
  • 主要是用Html.ImageGetter來實(shí)現(xiàn)

  • 接口返回的html字段中撤嫩,有可能包含多個(gè)網(wǎng)絡(luò)圖片的地址序攘,這時(shí)候需要下載圖片到本地。

  • 第一次顯示的時(shí)候只是把文字部分加載出來丈牢,等到圖片加載完成的時(shí)候瞄沙,再一次賦值給Textview就實(shí)現(xiàn)了上面動(dòng)圖的效果距境。

2肮疗、DownLoadHtmlImageUtils 圖片下載工具類
/**
 * 項(xiàng)目名:xyjyyth
 * 包名:  com.tecsun.tsb.utils
 * 文件名:DownLoadHtmlImageUtils
 * 創(chuàng)建者:ZhuiMengXiaoLe
 * 日期:  2017/10/31 18:59
 * 描述:  下載Html標(biāo)簽里面的圖片
 */
public class DownLoadHtmlImageUtils {
    public volatile boolean isCancle = false;
    // Init Hander
    EventHandler mHandler = new EventHandler(this);

    /**
     * DownLoad the file that must have a url
     *
     * @param url The http url
     * @param savePath The save path
     */
    public void download(final String url, final String savePath) {
        Log.i("DEBUG", url+"  Start!");
        new Thread(new Runnable() {
            public void run() {
                try {
                    Log.i("DEBUG", url+"  Start !!!!");
                    sendMessage(FILE_DOWNLOAD_CONNECT);
                    URL sourceUrl = new URL(url);
                    URLConnection conn = sourceUrl.openConnection();
                    InputStream inputStream = conn.getInputStream();

                    int fileSize = conn.getContentLength();

                    File savefile = new File(savePath);
                    if (savefile.exists()) {
                        savefile.delete();
                    }
                    savefile.createNewFile();

                    FileOutputStream outputStream = new FileOutputStream(savePath);

                    byte[] buffer = new byte[1024];
                    int readCount = 0;
                    int readNum = 0;
                    int prevPercent = 0;
                    while ((readNum = inputStream.read(buffer)) != -1) {
                        if (readNum > -1) {
                            readCount = readCount + readNum;
                            outputStream.write(buffer, 0, readNum);

                            int percent = (readCount * 100 / fileSize);
                            if (percent > prevPercent) {
                                // send the progress
                                sendMessage(FILE_DOWNLOAD_UPDATE, percent, readCount);
                                prevPercent = percent;
                            }

                            if (isCancle) {
                                outputStream.close();
                                sendMessage(FILE_DOWNLOAD_ERROR, new Exception("Stop"));
                                break;
                            }
                        }
                    }

                    outputStream.close();
                    if (!isCancle) {
                        sendMessage(FILE_DOWNLOAD_COMPLETE, url);
                    }

                } catch (Exception e) {
                    sendMessage(FILE_DOWNLOAD_ERROR, e);
                    // Log.e("MyError", e.toString());
                }
            }
        }).start();
    }

    /**
     * send message to handler
     *
     * @param what handler what
     * @param obj handler obj
     */
    private void sendMessage(int what, Object obj) {
        // init the handler message
        Message msg = mHandler.obtainMessage(what, obj);
        // send message
        mHandler.sendMessage(msg);
    }

    private void sendMessage(int what) {
        Message msg = mHandler.obtainMessage(what);
        mHandler.sendMessage(msg);
    }

    private void sendMessage(int what, int arg1, int arg2) {
        Message msg = mHandler.obtainMessage(what, arg1, arg2);
        mHandler.sendMessage(msg);
    }

    public void setCancle() {
        this.isCancle = true;
        Log.v("setCancle", String.valueOf(isCancle));
    }

    private static final int FILE_DOWNLOAD_CONNECT = 0;
    private static final int FILE_DOWNLOAD_UPDATE = 1;
    private static final int FILE_DOWNLOAD_COMPLETE = 2;
    private static final int FILE_DOWNLOAD_ERROR = -1;

    // defined the handler
    private class EventHandler extends Handler {
        private final DownLoadHtmlImageUtils mManager;

        public EventHandler(DownLoadHtmlImageUtils manager) {
            mManager = manager;
        }

        // do the receive message
        @Override
        public void handleMessage(Message msg) {

            switch (msg.what) {
                case FILE_DOWNLOAD_CONNECT:
                    if (mOnDownloadListener != null)
                        mOnDownloadListener.onDownloadConnect(mManager);
                    break;
                case FILE_DOWNLOAD_UPDATE:
                    if (mOnDownloadListener != null)
                        mOnDownloadListener.onDownloadUpdate(mManager, msg.arg1);
                    break;
                case FILE_DOWNLOAD_COMPLETE:
                    if (mOnDownloadListener != null)
                        mOnDownloadListener.onDownloadComplete(mManager, msg.obj);
                    break;
                case FILE_DOWNLOAD_ERROR:
                    if (mOnDownloadListener != null)
                        mOnDownloadListener.onDownloadError(mManager, (Exception) msg.obj);
                    break;
                default:
                    break;
            }
        }
    }

    // defined connection listener
    private OnDownloadListener mOnDownloadListener;

    public interface OnDownloadListener {
        void onDownloadConnect(DownLoadHtmlImageUtils manager);
        void onDownloadUpdate(DownLoadHtmlImageUtils manager, int percent);
        void onDownloadComplete(DownLoadHtmlImageUtils manager, Object result);
        void onDownloadError(DownLoadHtmlImageUtils manager, Exception e);
    }

    public void setOnDownloadListener(OnDownloadListener listener) {
        mOnDownloadListener = listener;
    }
}
3钾怔、核心代碼1分析:設(shè)置TextView可點(diǎn)擊跳轉(zhuǎn)Html里面的鏈接
    //保存文件路徑
    private final String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/htmlimg/";
        //設(shè)置鏈接中標(biāo)簽是可以點(diǎn)擊并且可以跳轉(zhuǎn)到瀏覽器打開的
        tvJobDes.setClickable(true);
        tvJobDes.setMovementMethod(LinkMovementMethod.getInstance());
        //整個(gè)TextView居中顯示
//      tvJobDes.setGravity(Gravity.CENTER_HORIZONTAL);

4宗侦、核心代碼2分析:第一次賦值給 TextView,同時(shí)開始下載圖片
private void setData() {
        //初始化下載類
        downLoadUtils=new DownLoadHtmlImageUtils();
        //設(shè)置下載類監(jiān)聽事件
        downLoadUtils.setOnDownloadListener(onDownloadListener);
        //給Textview賦值
        tvJobDes.setText(Html.fromHtml(mFvalue,imageGetter,null));
    }
    Drawable drawable = null;
    Bitmap bitmap = null;
    Html.ImageGetter imageGetter = new Html.ImageGetter() {
        public Drawable getDrawable(String source) {

            String fileString=path+String.valueOf(source.hashCode());
            Log.i("DEBUG", fileString+"");
            Log.i("DEBUG", source+"");

            if (!new File(path).exists()){
                new File(path).mkdirs();
                LogUtils.d(TAG,"創(chuàng)建文件夾成功========");
            }
            //判斷SD卡里面是否存在圖片文件
            if (new File(fileString).exists()) {
                Log.i("DEBUG", fileString+"  eixts");
                //獲取本地文件返回Drawable
                bitmap = BitmapFactory.decodeFile(fileString);
                drawable = new BitmapDrawable(bitmap);
//              drawable=Drawable.createFromPath(fileString);
                //設(shè)置圖片邊界
                if (drawable != null){
                    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
                    return drawable;
                }
                return null;

            }else {
                Log.i("DEBUG", fileString+" Do not eixts");
                //啟動(dòng)新線程下載
                downLoadUtils.download(source, path+String.valueOf(source.hashCode()));
                return drawable;
            }

        };

    };
5姑裂、核心代碼3分析:等待圖片下載完成的時(shí)候,再一次賦值給TextView
DownLoadHtmlImageUtils.OnDownloadListener onDownloadListener=new DownLoadHtmlImageUtils.OnDownloadListener() {

        //下載進(jìn)度
        public void onDownloadUpdate(DownLoadHtmlImageUtils manager, int percent) {
            // TODO Auto-generated method stub
            Log.i("DEBUG", percent+"");
        }

        //下載失敗
        public void onDownloadError(DownLoadHtmlImageUtils manager, Exception e) {
            // TODO Auto-generated method stub

        }

        //開始下載
        public void onDownloadConnect(DownLoadHtmlImageUtils manager) {
            // TODO Auto-generated method stub
            Log.i("DEBUG", "Start  //////");
        }

        //完成下載
        public void onDownloadComplete(DownLoadHtmlImageUtils manager, Object result) {
            // TODO Auto-generated method stub
            Log.i("DEBUG", result.toString());
            //替換sTExt的值舶斧,就是把圖片的網(wǎng)絡(luò)路徑換成本地SD卡圖片路徑(最早想法茴厉,可以不需要這樣做了)
            //sText.replace(result.toString(), path+String.valueOf(result.hashCode()));
            //再一次賦值給Textview
            tvJobDes.setText(Html.fromHtml(mFvalue, imageGetter, null));
        }
    };
6、核心代碼4分析:退出Activity或者Fragment的時(shí)候怀酷,回收Bitmap
@Override
    protected void onDestroy() {
        super.onDestroy();
        drawable = null;

//因?yàn)楸緫?yīng)用要下載圖片太多蜕依,所以每次退出的時(shí)候把下載好的本地圖片刪除
        FileUtils.delDir(path);
        if (bitmap != null && !bitmap.isRecycled()){
            bitmap.recycle();
            bitmap = null;
            drawable = null;
        }

        if (imageGetter != null){
            imageGetter = null;
        }
    }
8琉雳、FileUtils工具類核心方法:為了刪除下載好的本地圖片
 /**
     * 刪除方法 這里只會(huì)刪除某個(gè)文件夾下的文件<br/>
     * 支持兩級(jí)目錄刪除
     */
    public static void delDir(String path) {
            File directory = new File(path);
            if (directory != null && directory.exists() && directory.isDirectory()) {
                for (File item : directory.listFiles()) {
                    if (item.isDirectory()) {
                        for (File img : item.listFiles()) {
                            img.delete();
                        }
                    }
                    item.delete();
                }
            }
    }
8咐吼、FileUtils工具類完整代碼
public class FileUtils {
    private static Context mContext;
    private static final int DELAY_TIME = 10000;

    public final static String CACHE_DIR = "CNMusic";
    public final static String GLIDE_CACHE_DIR = "glide";
    public final static String SONG_CACHE_DIR = "songs";

    public final static String APK_NAME = "cnmusic.apk";


    /**
     * 應(yīng)用關(guān)聯(lián)的圖片存儲(chǔ)空間
     *
     * @param context
     * @return
     */
    public static String getAppPictureDir(Context context) {
        File file = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        return file.getPath();
    }

    /**
     * 獲取緩存主目錄
     *
     * @return
     */
    public static String getMountedCacheDir() {
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            // 創(chuàng)建一個(gè)文件夾對(duì)象厢塘,賦值為外部存儲(chǔ)器的目錄
            File sdcardDir = Environment.getExternalStorageDirectory();
            //得到一個(gè)路徑肌幽,內(nèi)容是sdcard的文件夾路徑和名字
            String path = sdcardDir.getPath() + File.separator + CACHE_DIR;
            File path1 = new File(path);
            if (!path1.exists()) {
                path1.mkdirs();
            }
            return path1.getPath();
        }
        return null;
    }

    /**
     * 獲取存放歌曲的目錄
     *
     * @return
     */
    public static String getSongDir() {
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            String path = getMountedCacheDir() + File.separator + SONG_CACHE_DIR;
            File path1 = new File(path);
            if (!path1.exists()) {
                path1.mkdirs();
            }
            return path1.getPath();
        }
        return null;
    }

    /**
     * 獲取存放緩存的目錄
     *
     * @return
     */
    public static String getCacheDir() {
        File file = mContext.getExternalCacheDir();
        return file.getPath();
    }

    /**
     * 刪除方法 這里只會(huì)刪除某個(gè)文件夾下的文件<br/>
     * 支持兩級(jí)目錄刪除
     */
    public static void cleanCacheDir() {
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            File directory = mContext.getExternalCacheDir();
            if (directory != null && directory.exists() && directory.isDirectory()) {
                for (File item : directory.listFiles()) {
                    if (item.isDirectory()) {
                        for (File img : item.listFiles()) {
                            img.delete();
                        }
                    }
                    item.delete();
                }
            }
        }
    }

    /**
     * 刪除方法 這里只會(huì)刪除某個(gè)文件夾下的文件<br/>
     * 支持兩級(jí)目錄刪除
     */
    public static void delDir(String path) {
            File directory = new File(path);
            if (directory != null && directory.exists() && directory.isDirectory()) {
                for (File item : directory.listFiles()) {
                    if (item.isDirectory()) {
                        for (File img : item.listFiles()) {
                            img.delete();
                        }
                    }
                    item.delete();
                }
            }
    }


    /**
     * 獲取apk放置的地址
     *
     * @return
     */
    public static String getApkPath() {
        String apkPath = getCacheDir() + File.separator + APK_NAME;
        File file = new File(apkPath);
        if (file.exists()) {
            file.delete();
        }
        return file.getPath();
    }

    /**
     * 讀取Assets目錄下的文件
     *
     * @param context
     * @param name
     * @return
     */
    public static String getAssets(Context context, String name) {
        String result = null;
        try {
            InputStream in = context.getAssets().open(name);  //獲得AssetManger 對(duì)象, 調(diào)用其open 方法取得  對(duì)應(yīng)的inputStream對(duì)象
            int size = in.available();//取得數(shù)據(jù)流的數(shù)據(jù)大小
            byte[] buffer = new byte[size];
            in.read(buffer);
            in.close();
            result = new String(buffer);
        } catch (Exception e) {
        }
        return result;
    }

    /**
     * 媒體掃描,防止下載后在sdcard中獲取不到歌曲的信息
     *
     * @param path
     */
    public static void mp3Scanner(String path) {
        MediaScannerConnection.scanFile(mContext.getApplicationContext(),
                new String[]{path}, null, null);
    }

    public static boolean existFile(String path) {
        File path1 = new File(path);
        return path1.exists();
    }

    public static boolean deleteFile(String path) {
        File path1 = new File(path);
        if (path1.exists()) {
            return path1.delete();
        }
        return false;
    }

    /**
     * open apk
     *
     * @param context
     * @param apk
     */
    public static void openApk(Context context, File apk) {
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(apk),
                "application/vnd.android.package-archive");
        context.startActivity(intent);
    }


    /**
     * 獲取下載文件的大小
     *
     * @param soFarBytes 已下載字節(jié)
     * @param totalBytes 總共的字節(jié)
     * @return
     */
    public static String getProgressSize(long soFarBytes, long totalBytes) {
        float progress = soFarBytes * 1.0f / 1024 / 1024;
        float total = totalBytes * 1.0f / 1024 / 1024;
        String format = "%.1fM/%.1fM";
        String str = String.format(Locale.CHINA, format, progress, total);
        return str;
    }

    /**
     * 獲取下載進(jìn)度
     *
     * @param soFarBytes 已下載字節(jié)
     * @param totalBytes 總共的字節(jié)
     * @return
     */
    public static int getProgress(long soFarBytes, long totalBytes) {
        if (totalBytes != 0) {
            long progress = soFarBytes * 100 / totalBytes;
            return (int) progress;
        }
        return 0;
    }

    /**
     * download apk from server
     *
     * @param path the apk path
     * @param fp   file progress listener
     * @return apk file
     * @throws Exception
     */
    public static File getFilefromServerToProgress(String path, FileProgress fp) throws Exception {
        //如果相等的話表示當(dāng)前的sdcard掛載在手機(jī)上并且是可用的
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(DELAY_TIME);
            int max = conn.getContentLength();
            InputStream is = conn.getInputStream();
            File file = new File(Environment.getExternalStorageDirectory(), "beats.apk");
            FileOutputStream fos = new FileOutputStream(file);
            BufferedInputStream bis = new BufferedInputStream(is);
            byte[] buffer = new byte[1024];
            int len;
            int total = 0;
            while ((len = bis.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
                total += len;
                //獲取當(dāng)前下載量
                if (fp != null)
                    fp.getProgress(total, max);
            }
            fos.close();
            bis.close();
            is.close();
            return file;
        } else {
            return null;
        }
    }

    private static Pattern FilePattern = Pattern.compile("[\\\\/:*?\"<>|]");

    public static String filenameFilter(String str) {
        return str == null ? null : FilePattern.matcher(str).replaceAll("");
    }


    public interface FileProgress {
        void getProgress(int total, int max);
    }



}
9狡孔、主Actiivity或者Fragment完整代碼實(shí)現(xiàn)
**
 * 發(fā)布信息詳情查詢
 * @author zlc
 *
 */
public class JobFbxxxqcxActivity extends BaseActivity {

    private static final String TAG = JobFbxxxqcxActivity.class.getSimpleName();
    private Context mContext;
    private TextView tvJobName;
    private TextView tvJobDes;
    private TextView tvJobTask;
    private TextView tvJobRequest;
    private ImageButton mImbBack;
    private JobIntentInfoBean mInfoBean;
    private String mFinfoid;
    private String mFvalue;
    private DownLoadHtmlImageUtils downLoadUtils;
    //保存文件路徑
    private final String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/htmlimg/";


    //  String sText = "測試圖片信息:<br><img src=\"http://pic004.cnblogs.com/news/201211/20121108_091749_1.jpg\" />";

    @Override
    protected void onCreate(Bundle arg0) {
        super.onCreate(arg0);
        setContentView(R.layout.activity_job_fbxxcx_32);
        AppApplication.getInstance().addActivity(this);
        initView();

        initListener();

        initData();
        
        getListData();
    }


    /**
     * 初始化數(shù)據(jù)的方法
     */
    private void initData() {
        mInfoBean = (JobIntentInfoBean) getIntent().getSerializableExtra
                (Constant.INTENT_CONTENT);
        if (mInfoBean != null){
            mFinfoid = mInfoBean.finfoid;
            LogUtils.d(TAG,"mFinfoid===="+mFinfoid);
        }
    }

    /**
     * 初始化監(jiān)聽的方法
     */
    private void initListener() {
        mImbBack.setOnClickListener(this);
    }

    @Override
    protected void initView() {
        mContext = this;
        loadingDialog = new LoadingDialog(this, R.string.tip_loading_msg);
        TextView tvTitle = (TextView) this.findViewById(R.id.tv_base_title_content);
        tvTitle.setText(R.string.title_fbxxxq);
        mImbBack = (ImageButton) this.findViewById(R.id.imgb_back);
        tvJobName = (TextView) findViewById(R.id.tv_job_name);
        tvJobDes = (TextView) findViewById(tv_job_des);
        tvJobTask = (TextView) findViewById(R.id.tv_job_task);
        tvJobRequest = (TextView) findViewById(R.id.tv_job_request);

        //設(shè)置鏈接中標(biāo)簽是可以點(diǎn)擊并且可以跳轉(zhuǎn)到瀏覽器打開的
        tvJobDes.setClickable(true);
        tvJobDes.setMovementMethod(LinkMovementMethod.getInstance());
        //整個(gè)TextView居中顯示
//      tvJobDes.setGravity(Gravity.CENTER_HORIZONTAL);

    }
    
    @Override
    public void onClick(View v) {
        super.onClick(v);
        switch (v.getId()) {
            case R.id.imgb_back:
                finish();
                EventBus.getDefault().post(true);
        }
    }

    /**
     * 查詢個(gè)人求職列表信息
     */
    private void getListData() {
        showLoadingDialog();
        StringEntity entity = new JobParam().getCmsInfoParam(mFinfoid);
        HttpUtil.post(this, APICommon.API_GETCMSINFO, entity, new AsyncHttpResponseHandler() {
            
            @Override
            public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
                LogUtils.d(new String(responseBody));
                Gson gson = new Gson();
                FbxxxqDataListResponse bean = gson.fromJson(new String
                        (responseBody), FbxxxqDataListResponse.class);
                loadPersionData(bean);
                dismissLoadingDialog();
            }
            
            @Override
            public void onFailure(int statusCode, Header[] headers,
                    byte[] responseBody, Throwable error) {
                dismissLoadingDialog();

            }
        });
    }
    
    /**
     * 界面加載數(shù)據(jù)
     * @param bean
     */
    @SuppressWarnings("unchecked")
    private void loadPersionData(FbxxxqDataListResponse bean) {
        if (!bean.isSuccess()) {

            return;
        }
        if (bean != null) {
            List<InfoidDataResponse> infoidDataResponseList = bean.data;
            if (infoidDataResponseList.size() > 0){
                InfoidDataResponse infoidDataResponse = infoidDataResponseList.get(0);
                mFvalue = infoidDataResponse.getFvalue();
                if (!TextUtils.isEmpty(mFvalue)){
                    setData();
                }else {
                    showWarnStrDialog("發(fā)布信息詳情為空");
                }

            }
        }
    }

    private void setData() {
        //初始化下載類
        downLoadUtils=new DownLoadHtmlImageUtils();
        //設(shè)置下載類監(jiān)聽事件
        downLoadUtils.setOnDownloadListener(onDownloadListener);
        //給Textview賦值
        tvJobDes.setText(Html.fromHtml(mFvalue,imageGetter,null));
    }
    Drawable drawable = null;
    Bitmap bitmap = null;
    Html.ImageGetter imageGetter = new Html.ImageGetter() {
        public Drawable getDrawable(String source) {

            String fileString=path+String.valueOf(source.hashCode());
            Log.i("DEBUG", fileString+"");
            Log.i("DEBUG", source+"");

            if (!new File(path).exists()){
                new File(path).mkdirs();
                LogUtils.d(TAG,"創(chuàng)建文件夾成功========");
            }
            //判斷SD卡里面是否存在圖片文件
            if (new File(fileString).exists()) {
                Log.i("DEBUG", fileString+"  eixts");
                //獲取本地文件返回Drawable
                bitmap = BitmapFactory.decodeFile(fileString);
                drawable = new BitmapDrawable(bitmap);
//              drawable=Drawable.createFromPath(fileString);
                //設(shè)置圖片邊界
                if (drawable != null){
                    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
                    return drawable;
                }
                return null;

            }else {
                Log.i("DEBUG", fileString+" Do not eixts");
                //啟動(dòng)新線程下載
                downLoadUtils.download(source, path+String.valueOf(source.hashCode()));
                return drawable;
            }

        };

    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        drawable = null;
        FileUtils.delDir(path);
        if (bitmap != null && !bitmap.isRecycled()){
            bitmap.recycle();
            bitmap = null;
            drawable = null;
        }

        if (imageGetter != null){
            imageGetter = null;
        }
    }

    Html.TagHandler MyTagHandler  = new Html.TagHandler() {
        @Override
        public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {

        }
    };

    DownLoadHtmlImageUtils.OnDownloadListener onDownloadListener=new DownLoadHtmlImageUtils.OnDownloadListener() {

        //下載進(jìn)度
        public void onDownloadUpdate(DownLoadHtmlImageUtils manager, int percent) {
            // TODO Auto-generated method stub
            Log.i("DEBUG", percent+"");
        }

        //下載失敗
        public void onDownloadError(DownLoadHtmlImageUtils manager, Exception e) {
            // TODO Auto-generated method stub

        }

        //開始下載
        public void onDownloadConnect(DownLoadHtmlImageUtils manager) {
            // TODO Auto-generated method stub
            Log.i("DEBUG", "Start  //////");
        }

        //完成下載
        public void onDownloadComplete(DownLoadHtmlImageUtils manager, Object result) {
            // TODO Auto-generated method stub
            Log.i("DEBUG", result.toString());
            //替換sTExt的值离唐,就是把圖片的網(wǎng)絡(luò)路徑換成本地SD卡圖片路徑(最早想法问窃,可以不需要這樣做了)
            //sText.replace(result.toString(), path+String.valueOf(result.hashCode()));
            //再一次賦值給Textview
            tvJobDes.setText(Html.fromHtml(mFvalue, imageGetter, null));
        }
    };
}
11泡躯、存在的問題
  • 當(dāng)接口返回里面包含很多<img>標(biāo)簽丽焊,也就是說要加載很多張圖片咕别,或許這些圖片都是大圖惰拱,那么如何做到更好的緩存呢?我嘗試過先判斷本地有沒有對(duì)應(yīng)的圖片欣孤,沒有的話就去下載昔逗,有的話沿用本地圖片勾怒,不過還是會(huì)報(bào)內(nèi)存溢出。(這里我沒有對(duì)圖片進(jìn)行壓縮段只,因?yàn)槲铱吹较螺d的圖片都是幾十kb或者100多kb)
  • <p style="TEXT-ALIGN: center> 圖片居中的標(biāo)簽不起作用鉴扫,居中不了

哪位大神有知道如何實(shí)現(xiàn)的坪创,麻煩告知下

12、參考文章

1古话、https://app.yinxiang.com/shard/s71/nl/14923130/5d9a8167-f62a-45b7-94ae-7ac0318021ba/
2锁施、https://app.yinxiang.com/shard/s71/nl/14923130/0af86dd4-3751-4a6c-b911-c2d170787ba4/
3悉抵、https://app.yinxiang.com/shard/s71/nl/14923130/446ec74b-41ad-4b7e-bedc-e7f2ddb09228/
4摘完、https://app.yinxiang.com/shard/s71/nl/14923130/3acfca20-fc98-4742-ad36-bded31dc754b/
ps:本博文的代碼有一部分是沿用上面大神的代碼孝治,有些是在上面的基礎(chǔ)上進(jìn)行了修改

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市岂座,隨后出現(xiàn)的幾起案子费什,更是在濱河造成了極大的恐慌,老刑警劉巖瘩蚪,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疹瘦,死亡現(xiàn)場離奇詭異巡球,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)呢灶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門鸯乃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來跋涣,“玉大人陈辱,你說我怎么就攤上這事÷兀” “怎么了利赋?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵媚送,是天一觀的道長塘偎。 經(jīng)常有香客問我拿霉,道長咱扣,這世上最難降的妖魔是什么偏窝? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任祭往,我火速辦了婚禮,結(jié)果婚禮上驮肉,老公的妹妹穿的比我還像新娘已骇。我一直安慰自己,他們只是感情好卵渴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布浪读。 她就那樣靜靜地躺著碘橘,像睡著了一般吱肌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纺蛆,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天犹撒,我揣著相機(jī)與錄音粒褒,去河邊找鬼奕坟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛刃跛,可吹牛的內(nèi)容都是我干的苛萎。 我是一名探鬼主播腌歉,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼桂塞!你這毒婦竟也來了阁危?” 一聲冷哼從身側(cè)響起汰瘫,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤混弥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后浙宜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛹磺,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡萤捆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年俗或,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了辛慰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡驰弄,死狀恐怖戚篙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情位喂,我是刑警寧澤乱灵,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布阔蛉,位于F島的核電站状原,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏削锰。R本人自食惡果不足惜毕莱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一朋截、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧唆姐,春花似錦廓八、人聲如沸剧蹂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽筹裕。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抗斤,已是汗流浹背丈咐。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國打工棵逊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人徒像。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓锯蛀,卻偏偏與公主長得像次慢,于是被迫代替她去往敵國和親迫像。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容