Recently, when we did the project function, we needed to display the text in the TextView. At first, we thought it was very simple, just use an ImageView and TextView to display the text. However, we found that this did not achieve the effect we needed, so we need to involve the rich text TextView to display the text. Here are two ways to display static pictures and dynamic GIF images:

Static picture text and text: the effect is as follows:

Code:

		String content = "My worst moment is I wish I could have communicated better with that young man," O 'Neal said. "Because people always say if we hadn't split up, we could have won six or seven championships together. Looking at what lebron has done over the last seven years, I often say to myself, if we could have done that, we could have won six, seven, eight championships."; SpannableString sp = new SpannableString(content); Drawable Drawable = getDrawable(r.drawable. Activity_jing); drawable.setBounds(0, 0, 20, 20); / / set the size of the display pictures / / drawable setBounds (0, 0, drawable. GetMinimumWidth (), drawable. GetMinimumHeight ()); ImageSpan CenterAlignImageSpan imageSpan = new CenterAlignImageSpan(drawable); sp.setSpan(imageSpan, 0, 1, ImageSpan.ALIGN_BASELINE); Textone.settext (sp); textone.settext (sp);Copy the code

CenterAlignImageSpan utility class:

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, floatx, 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; // Calculate the y displacement canvas.save(); canvas.translate(x, transY); // Draw the image a distance b.draw(canvas); canvas.restore(); }}Copy the code

GIF graphics: the effect is as follows:

First we use THE HTML, parse into Spanned, and then set the Span to achieve text and text mix, the code is as follows:

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); }}}Copy the code

Image display is implemented using ImageSpan, but the default image display GIF image is static take the first frame, we can use Glide to retrieve the image to play GIF, Glide is the image loading library, this library is widely used in Google open source projects. Including the official app released at Google I/O in 2014. Glide and Picasso are 90 percent alike. To be exact, they are Picasso clones. But there are some differences in the details. And the performance is more optimized.

Glide into our project, and then create UrlDrawable and GlideImageGetter

Code can refer to: the bottom of the public number reply “rich text” can be obtained

Method call:

		String content = "My worst moment is I wish I could have communicated better with that young man," O 'Neal said. "Because people always say if we hadn't split up, we could have won six or seven championships together. Looking at what lebron has done over the last seven years, I often say to myself, if we could have done that, we could have won six, seven, eight championships.";
		String html = "<img src=\"file:///android_asset/i8live_activity_jing.gif\">" + content;
                ImageTextUtil.setImageText(textTwo, html);
Copy the code

The following is our personal public account (LongXuanzhigu). Our articles will be synchronized to this account, which is convenient for exchanging and learning Android knowledge and sharing personal favorite articles: