参考了两个网站的解决办法:
http://blog.csdn.net/qihigh/article/details/13776431
http://www.jb51.net/article/36660.htm
但是还是有一个问题没有解决:当没有文字内容,只有表情内容时,表情就会偏上。
调试发现有文字时和没文字时,自定义的ImageSpan的draw方法,传进来的bound.bottom是不一样的。当有文字时,传进来的bottom比textview的行高稍大一点,但是没有文字只有表情的时候,传进来的bottom与textview的行高相等,于是修改一下draw方法,判断一下即可。
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.text.style.ImageSpan;
/**
* 处理文字与表情图片不对齐的问题
* @author Administrator
*
*/
public class StickerSpan extends ImageSpan {
int lineSpace = 0;
int lineHeight = 0;
public StickerSpan(Drawable d, String source, int verticalAlignment) {
super(d, source, verticalAlignment);
// TODO Auto-generated constructor stub
}
public StickerSpan(Drawable d, String source) {
super(d, source);
// TODO Auto-generated constructor stub
}
public void setTvLineSpace(int space){
lineSpace = space;
}
public void setTvLineHeight(int h){
lineHeight = h;
}
@Override
public void draw(Canvas canvas, CharSequence text,
int start, int end, float x,
int top, int y, int bottom, Paint paint) {
Drawable b = getDrawable();
canvas.save();
int transY = bottom - b.getBounds().bottom - lineSpace;
if(bottom == lineHeight){
// transY = 0;
// transY = lineSpace/2;
transY = (bottom - b.getBounds().bottom)/2;
}else if (mVerticalAlignment == ALIGN_BASELINE) {
int textLength = text.length();
for (int i = 0; i < textLength; i++) {
if (Character.isLetterOrDigit(text.charAt(i))) {
transY -= paint.getFontMetricsInt().descent;
break;
}
}
}
canvas.translate(x, transY);
b.draw(canvas);
canvas.restore();
}
}
使用的时候,先设置好行高和行间距
int lineHeight = tv.getLineHeight();
int lineSpace = (int) (lineHeight - tv.getTextSize()*1.08);
span = new StickerSpan(drawable, source, verticalAlignment);
span.setTvLineSpace(tvLineSpace);
span.setTvLineHeight(tvLineHeight);
就是这样。