Android TextView图文混排,图片和文字居中对齐

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

1.下图是项目中一个UI需求
Android TextView图文混排,图片和文字居中对齐_第1张图片

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

我们可以通过图文混排来解决上述问题,通过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);
    }
}

你可能感兴趣的:(Android,UI)