textview 垂直居中_在Textview左边或右边添加图标 ,换行不错位

e872247bf50e9b3d162ee6357c1c2eb2.png

平日开发过程中,我们难免会遇到一些图文混排的格式,文字,自然是利用TextView控件去实现,若是单行文字,相信无论是左边还是右边添加图片对小伙伴们来说都不是难事,而且可以利用drawableleft或者直接利用ImageView实现就可以了。

1269a1d942f5beee7836c43c76aa359f.png

不过,若是要求文字显示多行时,无论是利用drawableleft,还是ImageView,想要做到换行不错位,都是不可能的,此时,我们就要利用富文本显示效果的SpannableString了。

SpannableString其实和String一样,都是一种字符串类型,SpannableString可以直接作为TextView的显示文本,不同的是SpannableString可以通过使用其方法setSpan方法实现字符串各种形式风格的显示,重要的是可以指定设置的区间,也就是为字符串指定下标区间内的子字符串设置格式。

至于SpannableString的各种用法,这里就不多做介绍了,感兴趣的小伙伴可以查看这篇文章

>https://www.cnblogs.com/qynprime/p/8026672.html

下面是针对textview左右添加图标换行不错位的代码实现

    SpannableString spannableString = new SpannableString(" " + item.getGod_des());
    Drawable drawable = mContext.getResources().getDrawable(R.mipmap.loading);
    drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
    spannableString.setSpan(new VerticalImageSpan(drawable), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    mtv.setText(spannableString);

关于上面代码

1.创建出SpannableString后,参数的item.getGod_des()为你的textview要显示的内容,为什么要在前面加上一个空格呢?

因为这个空格就是你的图标要占的位置,所以多加一个空格为图标腾出一个位置,否则图标会默认占用第一个字来显示,如果图标与文字之间想留间隙,还可以多加一个空格。

2.把你的图标转成一个drawable,并且给drawable设置最小宽高。

3.VerticalImageSpan: 这个是一个可以垂直居中的ImageSpan,实现代码会放在下边

4.解释一下0,1: 开始位置从0开始,到第一个位置结束。 如果大家想在最后面加上图标,可以把0换成字符串长度-1,把1换成字符串长度,切记要在后面加一个空格占位,否则会切割掉你原本的字符串哦。

5.设置textview,这个就不多说了

VerticalImageSpan的代码

    public class VerticalImageSpan extends ImageSpan {

    public VerticalImageSpan(Drawable drawable) {
        super(drawable);

    }

    public VerticalImageSpan(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();
    }
    }

基本的代码就是上面这两段,不过,针对这种经常用得到的代码,我们其实可以封装成一个工具类,平时用到时,只需要传入文字和图标,就可以实现想要的效果。

    工具类代码
    public class TextAndPictureUtil {
        private TextAndPictureUtil mTextAndPictureUtil;
        private TextAndPictureUtil(){}
        public  TextAndPictureUtil getInstance(){
            if (mTextAndPictureUtil==null){
                synchronized (TextAndPictureUtil.class){
                    if (mTextAndPictureUtil==null){
                        mTextAndPictureUtil=new TextAndPictureUtil();
                    }
                }
            }
            return mTextAndPictureUtil;
        }

        public static SpannableString getText(Context mcontext,String text, int drawId){
            SpannableString spannableString = new SpannableString("  " + text);
            Drawable drawable = mcontext.getResources().getDrawable(drawId);
            drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
            spannableString.setSpan(new VerticalImageSpan(drawable), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            return spannableString;
        }
    }

调用

   TextAndPictureUtil.getInstance().getText("IT烟酒僧",R.drawable.it)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值