TextView for Android Control to Mix Static Graphics with Dynamic GIF Graphics

Posted by angel777 on Tue, 27 Aug 2019 04:35:03 +0200

Recently, when working on project functions, you need to display text in TextView. At first, you thought it was simple. Just use an ImageView and a TextView to display, but you found that doing so does not achieve the desired effect. This involves rich text TextView to display text. Here's a static pictureGraphics and text of dynamic GIF are displayed in two ways:

Text for still pictures:
The results are as follows:

Code:

        String content = ""My worst moment was when I wished I could have been with that young man (Kobe)-Bryant) There's better communication,"O'Neill said."Because people often say that if we don't separate, we might get 6 or 7 champions together.Looking at what LeBron (James) has done over the past seven years, I often tell myself that if we had solved it, we would have won 6, 7 or even 8 champions";
        SpannableString sp = new SpannableString(content);
        //Get a picture
        Drawable drawable = getDrawable(R.drawable.activity_jing);
        drawable.setBounds(0, 0, 20, 20);//Set the size of the display picture
        //Drawable.setBounds (0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight(); //Set the size of the display picture

        //Center aligned imageSpan
        CenterAlignImageSpan imageSpan = new CenterAlignImageSpan(drawable);
        sp.setSpan(imageSpan, 0, 1, ImageSpan.ALIGN_BASELINE);//0,1 represents the starting position of the display picture, occupying one word
        textOne.setText(sp);

CenterAlignImageSpan tool 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, 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;//Calculate displacement in y direction
        canvas.save();
        canvas.translate(x, transY);//Draw pictures to shift a distance
        b.draw(canvas);
        canvas.restore();
    }
}

Text for dynamic GIF:
The results are as follows:

First, we use html, parse it into Spanned, and then set up Span to mix text and graphics. 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);
        }
    }
}

The code picture display above is achieved through ImageSpan, but the default picture display gif picture is static first frame picture, we can use Glide to play gif when we get the picture, glide is the picture loading library, which is widely used in google's open source projects, including google I/O in 2014Official app released at the meeting.Glide and Picasso have a 90% similarity, which is exactly a cloned version of Picasso.But there are many differences in detail.And the performance is more optimized.

Bring Glide into our project and create UrlDrawable and GlideImageGetter

Code available for reference: bottom public number reply "Rich Text" is available

Method calls:

        String content = ""My worst moment was when I wished I could have been with that young man (Kobe)-Bryant) There's better communication,"O'Neill said."Because people often say that if we don't separate, we might get 6 or 7 champions together.Looking at what LeBron (James) has done over the past seven years, I often tell myself that if we had solved it, we would have won 6, 7 or even 8 champions";
        String html = "<img src=\"file:///android_asset/i8live_activity_jing.gif\">" + content;
        ImageTextUtil.setImageText(textTwo, html);

The following is the Personal Public Number (longxuanzhigu), which will be synchronized with the published articles to facilitate the exchange of Android knowledge and sharing of personal favorite articles:

Topics: Android Google