Android控件TextView实现静态图与动态GIF图文混排

最近作项目功能时,须要在TextView中展现图文,刚开始作的时候觉得很简单,只须要用个ImageView跟TextView来展现就好了,但是发现这样作,不能实现咱们须要的效果,这就须要涉及到富文本TextView来展现图文,下面介绍静态图片的图文和动态GIF的图文两种展现方式:html

静态图片的图文: 效果以下: android

这里写图片描述

代码:canvas

String content = "“我最糟糕的时刻,就是我但愿本身当初能与那个年轻人(科比-布莱恩特)有更好的沟通,”奥尼尔说道,“由于人们常说,若是咱们俩没有分开,咱们可能能够一块儿获得六、7个冠军。看着勒布朗(詹姆斯)过去7年作到的事情,我也常对本身说,若是咱们当初可以解决好,咱们可能会获得六、7个甚至8个冠军";
		SpannableString sp = new SpannableString(content);
        //获取一张图片
        Drawable drawable = getDrawable(R.drawable.activity_jing);
        drawable.setBounds(0, 0, 20, 20);//设置展现图片的大小
        //drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());//设置展现图片的大小

        //居中对齐imageSpan
        CenterAlignImageSpan imageSpan = new CenterAlignImageSpan(drawable);
        sp.setSpan(imageSpan, 0, 1, ImageSpan.ALIGN_BASELINE);//0,1表示展现图片的起始位置,占一个字的位置
        textOne.setText(sp);
复制代码

CenterAlignImageSpan工具类:bash

public class CenterAlignImageSpan extends ImageSpan {

    public CenterAlignImageSpan(Drawable drawable) {
        super(drawable);

    }

    public CenterAlignImageSpan(Bitmap b) {
        super(b);
    }

    @Override
    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom,
                     @NonNull Paint paint) {

        Drawable b = getDrawable();
        Paint.FontMetricsInt fm = paint.getFontMetricsInt();
        int transY = (y + fm.descent + y + fm.ascent) / 2 - b.getBounds().bottom / 2;//计算y方向的位移
        canvas.save();
        canvas.translate(x, transY);//绘制图片位移一段距离
        b.draw(canvas);
        canvas.restore();
    }
}
复制代码

动态GIF的图文: 效果以下: app

这里写图片描述

首先咱们使用的html,解析成Spanned,而后设置Span来实现图文混排的,代码以下:ide

public class ImageTextUtil {

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

    }
    

    public static void setImageText(TextView tv, String 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);
        }
    }
}
复制代码

上面代码图片展现是经过ImageSpan来实现的,但默认的图片展现的gif图片是静态取第一帧图片,咱们能够在获取图片时候使用Glide,来实现播放gif,glide是图片加载库,这个库被普遍的运用在google的开源项目中,包括2014年google I/O大会上发布的官方app。Glide和Picasso有90%的类似度,准确的说,就是Picasso的克隆版本。可是在细节上仍是有很多区别的。并且性能上更加优化。工具

把Glide引入到咱们项目中,而后在建立UrlDrawable 和 GlideImageGetter性能

代码能够参考:底部公众号回复"富文本"便可获取学习

方法调用:优化

String content = "“我最糟糕的时刻,就是我但愿本身当初能与那个年轻人(科比-布莱恩特)有更好的沟通,”奥尼尔说道,“由于人们常说,若是咱们俩没有分开,咱们可能能够一块儿获得六、7个冠军。看着勒布朗(詹姆斯)过去7年作到的事情,我也常对本身说,若是咱们当初可以解决好,咱们可能会获得六、7个甚至8个冠军";
		String html = "<img src=\"file:///android_asset/i8live_activity_jing.gif\">" + content;
                ImageTextUtil.setImageText(textTwo, html);
复制代码

如下是我的公众号(longxuanzhigu),以后发布的文章会同步到该公众号,方便交流学习Android知识及分享我的爱好文章:

这里写图片描述
相关文章
相关标签/搜索