Android控件TextView實現靜態(tài)圖與動態(tài)GIF圖文混排

最近做項目功能時,需要在TextView中展示圖文,剛開始做的時候以為很簡單,只需要用個ImageView跟TextView來展示就行了,可是發(fā)現這樣做,不能實現我們需要的效果,這就需要涉及到富文本TextView來展示圖文,下面介紹靜態(tài)圖片的圖文和動態(tài)GIF的圖文兩種展示方式:

靜態(tài)圖片的圖文:
效果如下:


這里寫圖片描述

代碼:

        String content = "“我最糟糕的時刻,就是我希望自己當初能與那個年輕人(科比-布萊恩特)有更好的溝通,”奧尼爾說道,“因為人們常說,如果我們倆沒有分開,我們可能可以一起得到6、7個冠軍??粗詹祭剩ㄕ材匪梗┻^去7年做到的事情,我也常對自己說,如果我們當初能夠解決好,我們可能會得到6、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工具類:

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();
    }
}

動態(tài)GIF的圖文:
效果如下:


這里寫圖片描述

首先我們使用的html,解析成Spanned,然后設置Span來實現圖文混排的,代碼如下:

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圖片是靜態(tài)取第一幀圖片,我們可以在獲取圖片時候使用Glide,來實現播放gif,glide是圖片加載庫,這個庫被廣泛的運用在google的開源項目中,包括2014年google I/O大會上發(fā)布的官方app。Glide和Picasso有90%的相似度,準確的說,就是Picasso的克隆版本。但是在細節(jié)上還是有不少區(qū)別的。而且性能上更加優(yōu)化。

把Glide引入到我們項目中,然后在創(chuàng)建UrlDrawable 和 GlideImageGetter

代碼可以參考:底部公眾號回復"富文本"即可獲取

方法調用:

        String content = "“我最糟糕的時刻,就是我希望自己當初能與那個年輕人(科比-布萊恩特)有更好的溝通,”奧尼爾說道,“因為人們常說,如果我們倆沒有分開,我們可能可以一起得到6、7個冠軍??粗詹祭剩ㄕ材匪梗┻^去7年做到的事情,我也常對自己說,如果我們當初能夠解決好,我們可能會得到6、7個甚至8個冠軍";
        String html = "<img src=\"file:///android_asset/i8live_activity_jing.gif\">" + content;
        ImageTextUtil.setImageText(textTwo, html);

以下是個人公眾號(longxuanzhigu),之后發(fā)布的文章會同步到該公眾號,方便交流學習Android知識及分享個人愛好文章:


這里寫圖片描述
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容