美文网首页
Android Texview图文混排

Android Texview图文混排

作者: W会痛的石头 | 来源:发表于2022-02-13 13:33 被阅读0次

    Textview通常用来显示文本,但有时候为了满足设计的需求,我们应该怎样去实现呢。今天我们就用SpannableString来解决这个问题。

    image.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);
    }
    }
    

    注意:如果图片后字符串被遮挡,可以用空字符串代替(占位)。
    如果图片与字符串有间距,可以在字符串前加空字符串占位

    另: SpannableString详细解析
    https://www.jianshu.com/p/472fd3e32324

    相关文章

      网友评论

          本文标题:Android Texview图文混排

          本文链接:https://www.haomeiwen.com/subject/xfqxlrtx.html