1. 程式人生 > >Android TextView圖文混排,圖片和文字居中對齊

Android TextView圖文混排,圖片和文字居中對齊

TextView用來顯示文字是最普通的用法了,有些情況需要我們再文字中顯示圖片,比如顯示錶情,下邊來說說處理方法.

1.下圖是專案中一個UI需求
這裡寫圖片描述

如圖需要在文字的前邊顯示新上標籤,開始的處理方法是用了兩個空間分別顯示標籤和文字,但是有個問題是第二行的文字不能頂頭對齊,很不美觀.

我們可以通過圖文混排來解決上述問題,通過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);
    }
}