图文混排顾名思义就是把文字和图片混合排列在一起,比较简单的需求我们也可以通过TextView和ImageView配合使用来达到目的,但是遇到稍微复杂一些的情况这种方法就不适用了。

做这样一个按钮:

82888f98d7c0

对于你来说没有任何难度:LinearLayout+TextView+ImageView搞定;或者可以直接使用TextView的drawableLeft属性。

这里记录两种复杂情况的处理方法:

为部分文字添加点击事件;

图文混排,图片居中,图片可点击。

1. 为部分文字添加点击事件

我最终实现的效果是这个样子的:

82888f98d7c0

可点击文字显示为特殊颜色,并可以点击。个人觉得这个最大的特色就是可以像普通文本一样换行,这是组合控件所不能实现的。

这里使用了SpannableString和ClickableSpan实现,具体代码如下:

ClickSpan继承自ClickableSpan:

import android.text.TextPaint;

import android.text.style.ClickableSpan;

import android.view.View;

import com.travis.uqmei.utils.ToastUtil;

/**

* Created by travis on 16/9/18.

*/

public class ClickSpan extends ClickableSpan {

private String txt;

public ClickSpan(String txt){

this.txt = txt;

}

@Override

public void onClick(View widget) {

String content = String.format("ClickSpan is clicked, and txt is %s ",txt);

ToastUtil.show(content);

}

@Override

public void updateDrawState(TextPaint ds) {

//根据自己的需求定制文本的样式

ds.setColor(ds.linkColor);

ds.setUnderlineText(false);

}

}

为TextView设置部分文字可点击效果:

TextView tv = (TextView) findViewById(R.id.tv);

String from = "张全蛋";

String to = "赵铁柱";

String txt = String.format("%s回复@%s:我是富士康3号流水线的张全蛋," +

"英文名叫Micheal Jack,发文名叫helodie Jaqueline。", from, to);

SpannableString span = new SpannableString(txt);

ClickSpan clickSpan = new ClickSpan(to);

span.setSpan(clickSpan, txt.indexOf(to),

txt.indexOf(to) + to.length(),

Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

tv.setText(span);

tv.setMovementMethod(LinkMovementMethod

.getInstance());

2. 图文混排,图片居中,图片可点击

效果如下:

82888f98d7c0

可点击效果通过上述ClickSpan实现,图文混排通过VerticalImageSapn实现。

VerticalImageSpan继承自ImageSpan:

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.Rect;

import android.graphics.drawable.Drawable;

import android.text.style.ImageSpan;

/**

* 垂直居中的ImageSpan

*

* @author travis

*/

public class VerticalImageSpan extends ImageSpan {

public VerticalImageSpan(Drawable drawable) {

super(drawable);

}

public int getSize(Paint paint, CharSequence text, int start, int end,

Paint.FontMetricsInt fontMetricsInt) {

Drawable drawable = getDrawable();

Rect rect = drawable.getBounds();

if (fontMetricsInt != null) {

Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();

int fontHeight = fmPaint.bottom - fmPaint.top;

int drHeight = rect.bottom - rect.top;

int top = drHeight / 2 - fontHeight / 4;

int bottom = drHeight / 2 + fontHeight / 4;

fontMetricsInt.ascent = -bottom;

fontMetricsInt.top = -bottom;

fontMetricsInt.bottom = top;

fontMetricsInt.descent = top;

}

return rect.right;

}

@Override

public void draw(Canvas canvas, CharSequence text, int start, int end,

float x, int top, int y, int bottom, Paint paint) {

Drawable drawable = getDrawable();

canvas.save();

int transY = 0;

transY = ((bottom - top) - drawable.getBounds().bottom) / 2 + top;

canvas.translate(x, transY);

drawable.draw(canvas);

canvas.restore();

}

}

代码设置:

TextView tv = (TextView) findViewById(R.id.tv);

String icon = "icon";

String from = "张全蛋"+icon;

String to = "赵铁柱";

String txt = String.format("%s回复@%s:我是富士康3号流水线的张全蛋," +

"英文名叫Micheal Jack,发文名叫helodie Jaqueline。", from, to);

//设置ClickSpan,为部分文字("icon")添加点击效果

SpannableString span = new SpannableString(txt);

ClickSpan clickSpan = new ClickSpan(icon);

span.setSpan(clickSpan, txt.indexOf(icon),

txt.indexOf(icon) + icon.length(),

Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

//设置ImageSpan,占用可点击文字("icon")的位置

Bitmap bitmap = ImageUtils.resize(BitmapFactory.decodeResource(getResources(),

R.mipmap.uqmei_icon_contact), DensityUtil.sp2px(this, 12f));

BitmapDrawable drawable = new BitmapDrawable(bitmap);

drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());

span.setSpan(new VerticalImageSpan(drawable),

txt.indexOf(icon), txt.indexOf(icon) + icon.length(),

Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

//设置TextView

tv.setText(span);

tv.setHighlightColor(Color.TRANSPARENT);//消除点击时的背景色

tv.setMovementMethod(LinkMovementMethod.getInstance());

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐