android的图文混排(表情显示),Android TextView图文混排,图片和文字居中对齐

TextView用来显示文本是最普通的用法了,有些情况需要我们再文本中显示图片,比如显示表情,下边来说说处理方法.

1.下图是项目中一个UI需求

0818b9ca8b590ca3270a3433284dd417.png

如图需要在文本的前边显示新上标签,开始的处理方法是用了两个空间分别显示标签和文本,但是有个问题是第二行的文本不能顶头对齐,很不美观.

我们可以通过图文混排来解决上述问题,通过SpannableString来实现,在相应位置使用ImageSpan替换即可,但是imageSpan只提供了两种对齐方式,如下所示:

/**

底部对齐

*/

public static final int ALIGN_BOTTOM = 0;

/**

基线对齐

*/

public static final int ALIGN_BASELINE = 1;

但是通常UI设计肯定是图片和文字居中对齐

这里需要扩展继承ImageSpan,重写它的onDraw()方法

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

}

}

这是自定义ImageSpan的代码,非常少。主要的原理是把图片绘制在字体的descent线和ascent的中点位置。

在Activity中使用方法如下

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

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

SpannableString sp = new SpannableString("图文混排测排测试图文混排测试图文混排测试图文混排测试图");

//获取一张图片

Drawable drawable = getDrawable(R.drawable.star);

drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());

//居中对齐imageSpan

CenterAlignImageSpan imageSpan = new CenterAlignImageSpan(drawable);

sp.setSpan(imageSpan, 0, 1, ImageSpan.ALIGN_BASELINE);

//普通imageSpan 做对比

ImageSpan imageSpan2 = new ImageSpan(drawable);

sp.setSpan(imageSpan2, 3, 4, ImageSpan.ALIGN_BASELINE);

tv.setText(sp);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值