TextView加载 html 代码,借助Glide加载jpg or gif 等图片格式

app加载网页数据,可能大部分人都习惯用WebView去实现,简单方便,但是有些时候从api返回的html数据中,是不带html 的css样式的,这时候html 加载出来的文字会显示不整洁,达不到自己想要的效果,甚至文字很小,如果用WebView去显示的话,用户只能去拉伸放大去看,太碍事,大大的影响了用户体验,所以利用TextView去显示html文本,第一:可以自己控制字体大小及颜色,第二:可以利用Glide图片加载框架去load图片。

随意从数据中截取html代码:

<p style=\"text-align: center;\"><img style=\"max-width:600px;\" 

src=\"http://image.tv188.com/zhanbao/uploads/news/day_180516/201805162055438223.jpg\" alt=\"\"></p> \n<p style=\"text-indent:2em;\"> 

\n<p style=\"text-indent:2em;\"> \n<p style=\"text-indent:2em;\">在两队首回合较量中,缺少胡尔克的上港在客场1-3不敌鹿岛鹿角,埃尔克森为上港打进了一

粒关键的客场进球。此役,胡尔克火线复出,并进入首发阵容。在中超联赛中,虽然上港遭遇四轮不胜,但仍凭借净胜球优势高居榜首。值得注意的是,上港主场亚冠17战取得13胜4

平的不败战绩。</p> \n<p style=\"text-indent:2em;\">随着主裁判一声哨响,全场比赛开始。第2分钟,胡尔克后场送出精彩直塞,武磊右路高速插上,单刀杀到禁区前沿

一脚推射,权纯泰将球没收。</p> \n<p style=\"text-align: center;\"><img style=\"max-width:600px;\" 

src=\"http://image.tv188.com/zhanbao/mw690/005BUxg5gy1frdfmwu9w7g3086046hdt.gif\" alt=\"\"></p> \n<p style=\"text-indent:2em;\"> \n<p 

style=\"text-indent:2em;\"> \n<p style=\"text-indent:2em;\">第4分钟,胡尔克中场突然起脚吊射,皮球高出横梁。<strong>第6分钟,上港前场右路任意球传入

禁区,后点的鹿岛球员准备不足,胡尔克小禁区前沿迎球一脚扫射破网!上港主场1-0领先,将总比分扳为2-3!</strong></p> \n<p style=\"text-align: center;\">

<img style=\"max-width:600px;\" src=\"http://image.tv188.com/zhanbao/large/784fda03gy1frdfrlmt2bg208603x7wi.gif\" alt=\"\"></p> \n<p 

style=\"text-indent:2em;\"> \n<p style=\"text-align: center;\"><img style=\"max-width:600px;\" 

src=\"http://image.tv188.com/zhanbao/mw690/005BUxg5gy1frdfv2shk5g309p05ax6r.gif\" alt=\"\"></p> \n<p style=\"text-indent:2em;\"> 

里面包含了jpg,gif图片,开始动手了:
首先在项目gradle中添加glide: compile 'com.github.bumptech.glide:glide:3.7.0'

接下来layout.xml 里面简单,一个textview,用scrollview包裹这就行:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/white"
    android:padding="10dp">

    <TextView
        android:id="@+id/tv_detail_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@color/subtitle_color"
        android:textSize="@dimen/text16" />
</ScrollView>

一个工具类加载html代码:

package com.molie.tv188.utils;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.text.style.StyleSpan;
import android.text.style.URLSpan;
import android.view.View;
import android.widget.TextView;

/**
 * @author: Allen.
 * @date: 2018/6/26
 * @description: 图片文本工具类
 */

public class ImageTextUtil {
    public static Drawable getUrlDrawable(String source, TextView mTextView) {
        GlideImageGetter imageGetter = new GlideImageGetter(mTextView.getContext(), mTextView);
        return imageGetter.getDrawable(source);
    }

    /**
     * 加载 html代码
     * @param tv
     * @param html
     */
    public static void setImageText(TextView tv, String html) {
        if (!TextUtils.isEmpty(html)) { 
            Spanned htmlStr = Html.fromHtml(html);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                tv.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
                tv.setTextIsSelectable(true);
            }
            tv.setText(htmlStr);
            tv.setMovementMethod(LinkMovementMethod.getInstance());
            CharSequence text = tv.getText();
            if (text instanceof Spannable) {
                int end = text.length();
                Spannable sp = (Spannable) tv.getText();
                URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
                ImageSpan[] imgs = sp.getSpans(0, end, ImageSpan.class);
                StyleSpan[] styleSpens = sp.getSpans(0, end, StyleSpan.class);
                ForegroundColorSpan[] colorSpans = sp.getSpans(0, end, ForegroundColorSpan.class);
                SpannableStringBuilder style = new SpannableStringBuilder(text);
                style.clearSpans();
                for (URLSpan url : urls) {
                    style.setSpan(url, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.parseColor("#FF12ADFA"));
                    style.setSpan(colorSpan, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
                for (ImageSpan url : imgs) {
                    ImageSpan span = new ImageSpan(getUrlDrawable(url.getSource(), tv), url.getSource());
                    style.setSpan(span, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
                for (StyleSpan styleSpan : styleSpens) {
                    style.setSpan(styleSpan, sp.getSpanStart(styleSpan), sp.getSpanEnd(styleSpan), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
                for (ForegroundColorSpan colorSpan : colorSpans) {
                    style.setSpan(colorSpan, sp.getSpanStart(colorSpan), sp.getSpanEnd(colorSpan), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }

                tv.setText(style);
            }
        }
    }
}

加载图片实现Html.ImageGetter 和Drawable.callback 回调,GlideImageGetter.java:

package com.molie.tv188.utils;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.Html;
import android.view.View;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.Request;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.ViewTarget;
import com.molie.tv188.R;

import java.util.HashSet;
import java.util.Set;

/**
 * @author: Allen.
 * @date: 2018/6/26
 * @description: glide 加载图片
 */

public class GlideImageGetter implements Html.ImageGetter, Drawable.Callback {
    private final Context mContext;

    private final TextView mTextView;

    private final Set<ImageGetterViewTarget> mTargets;

    public static GlideImageGetter get(View view) {
        return (GlideImageGetter) view.getTag(R.id.drawable_tag);
    }

    public void clear() {
        GlideImageGetter prev = get(mTextView);
        if (prev == null) return;

        for (ImageGetterViewTarget target : prev.mTargets) {
            Glide.clear(target);
        }
    }

    public GlideImageGetter(Context context, TextView textView) {
        this.mContext = context;
        this.mTextView = textView;

//        clear(); //屏蔽掉这句在TextView中可以加载多张图片
        mTargets = new HashSet<>();
        mTextView.setTag(R.id.drawable_tag, this);
    }

    @Override
    public Drawable getDrawable(String url) {
        final UrlDrawableGlide urlDrawable = new UrlDrawableGlide();
        MainUtil.printLogger("Downloading from: " + url);
        Glide.with(mContext)
                .load(url)
                .skipMemoryCache(true)
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .into(new ImageGetterViewTarget(mTextView, urlDrawable));
        return urlDrawable;
    }

    @Override
    public void invalidateDrawable(Drawable who) {
        mTextView.invalidate();
    }

    @Override
    public void scheduleDrawable(Drawable who, Runnable what, long when) {

    }

    @Override
    public void unscheduleDrawable(Drawable who, Runnable what) {

    }

    private class ImageGetterViewTarget extends ViewTarget<TextView, GlideDrawable> {

        private final UrlDrawableGlide mDrawable;

        private ImageGetterViewTarget(TextView view, UrlDrawableGlide drawable) {
            super(view);
            mTargets.add(this);
            this.mDrawable = drawable;
        }

        @Override
        public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
            Rect rect;
            if (resource.getIntrinsicWidth() > 100) {
                float width;
                float height;
//                MainUtil.printLogger("Image width is " + resource.getIntrinsicWidth());
//                MainUtil.printLogger("View width is " + view.getWidth());
                if (resource.getIntrinsicWidth() >= getView().getWidth()) {
                    float downScale = (float) resource.getIntrinsicWidth() / getView().getWidth();
                    width = (float) resource.getIntrinsicWidth() / (float) downScale;
                    height = (float) resource.getIntrinsicHeight() / (float) downScale;
                } else {
                    float multiplier = (float) getView().getWidth() / resource.getIntrinsicWidth();
                    width = (float) resource.getIntrinsicWidth() * (float) multiplier;
                    height = (float) resource.getIntrinsicHeight() * (float) multiplier;
                }
                rect = new Rect(0, 0, Math.round(width), Math.round(height));
            } else {
                rect = new Rect(0, 0, resource.getIntrinsicWidth() * 2, resource.getIntrinsicHeight() * 2);
            }
            resource.setBounds(rect);

            mDrawable.setBounds(rect);
            mDrawable.setDrawable(resource);


            if (resource.isAnimated()) {
                mDrawable.setCallback(get(getView()));
                resource.setLoopCount(GlideDrawable.LOOP_FOREVER);
                resource.start();
            }

            getView().setText(getView().getText());
            getView().invalidate();
        }

        private Request request;

        @Override
        public Request getRequest() {
            return request;
        }

        @Override
        public void setRequest(Request request) {
            this.request = request;
        }
    }
}

自定义callback ,UrlDrawableGlide.java:

package com.molie.tv188.utils;

import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.drawable.Drawable;

import com.bumptech.glide.load.resource.drawable.GlideDrawable;

/**
 * @author: Allen.
 * @date: 2018/6/26
 * @description: glide 加载图片
 */

public class UrlDrawableGlide extends Drawable implements Drawable.Callback {
    private GlideDrawable mDrawable;

    @Override
    public void draw(Canvas canvas) {
        if (mDrawable != null) {
            mDrawable.draw(canvas);
        }
    }

    @Override
    public void setAlpha(int alpha) {
        if (mDrawable != null) {
            mDrawable.setAlpha(alpha);
        }
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        if (mDrawable != null) {
            mDrawable.setColorFilter(cf);
        }
    }

    @SuppressLint("WrongConstant")
    @Override
    public int getOpacity() {
        if (mDrawable != null) {
            return mDrawable.getOpacity();
        }
        return 0;
    }

    public void setDrawable(GlideDrawable drawable) {
        if (this.mDrawable != null) {
            this.mDrawable.setCallback(null);
        }
        drawable.setCallback(this);
        this.mDrawable = drawable;
    }

    @Override
    public void invalidateDrawable(Drawable who) {
        if (getCallback() != null) {
            getCallback().invalidateDrawable(who);
        }
    }

    @Override
    public void scheduleDrawable(Drawable who, Runnable what, long when) {
        if (getCallback() != null) {
            getCallback().scheduleDrawable(who, what, when);
        }
    }

    @Override
    public void unscheduleDrawable(Drawable who, Runnable what) {
        if (getCallback() != null) {
            getCallback().unscheduleDrawable(who, what);
        }
    }
}

在GlideImageGetter中 的R.id.drawable_tag ,需要在资源文件values文件夹中 创建ids.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="drawable_tag" type="id" />
</resources>

几乎完成了,使用的时候在activity中: ImageTextUtil.setImageText(tv_detail_content, htmlContent);

这里写图片描述

记得在AndroidManifest.xml清单文件中,相关的activity加上: android:hardwareAccelerated=”false”
如果项目中没有用到Webview播放html5网页视频的话,可以再Application中添加。

到此为止。。。。。。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值