图文混排
顾名思义就是把文字和图片混合排列在一起,比较简单的需求我们也可以通过TextView和ImageView配合使用来达到目的,但是遇到稍微复杂一些的情况这种方法就不适用了。
做这样一个按钮:
对于你来说没有任何难度:LinearLayout+TextView+ImageView搞定;或者可以直接使用TextView的drawableLeft属性。
这里记录两种复杂情况的处理方法:
- 为
部分文字
添加点击事件; - 图文混排,图片居中,图片可点击。
1. 为部分文字添加点击事件
我最终实现的效果是这个样子的:
可点击文字显示为特殊颜色,并可以点击。个人觉得这个最大的特色就是可以像普通文本一样换行,这是组合控件所不能实现的。
这里使用了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. 图文混排,图片居中,图片可点击
效果如下:
可点击效果通过上述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());