最近作項目功能時,須要在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知識及分享我的愛好文章: