当前位置: 移动技术网 > IT编程>移动开发>Android > TextView图文混排

TextView图文混排

2018年11月21日  | 移动技术网IT编程  | 我要评论

高军,热爱生命的手抄报,当灰姑娘遇上侯爵

大家都知道,textview有一个setcompounddrawables的方法来设置上下左右位置的图标,当然,也可以在xml布局文件中设置,然而问题来了,假如我们把图标放在左边,当我们让textview分多行显示的时候,会出现一种情况,左边的图标并不会与第一行对齐,而是与整个textview居中对齐。

即我们要的是下图:

结果是这个图:

怎么办呢?我们可以用图文混排:

我们可以利用spannablestring和imagespan。

1、构建spannablestring对象。

spannablestring spanstring = new spannablestring(textview.gettext().tostring());

2、获取drawable对象,即将我们的图案转换为drawable对象,并设置大小。

drawable tvdrawable = contextcompat.getdrawable(mcontext, r.drawable.pic);
tvdrawable.setbounds(0, 0, tvdrawable.getminimumwidth(), tvdrawable.getminimumheight());

3、构建imagespan 对象

imagespan span = new imagespan(tvdrawable, imagespan.align_baseline);

 4、设置给上面的spannablestring对象

spanstring.setspan(span, 0, 1, spannable.span_inclusive_exclusive);

5、最终设置给textview

textview.settext(spanstring)

 

加下来讲讲上面的方法:

1、imagespan对象,第二个参数为图像与文字的对齐方式,imagespan只带有两个对齐方式,分别是:align_baseline、align_bottom。

align_bottom 表示与文字内容的底部对齐,如果在构造imagespan时没有传入对齐方式,那么默认就是这种底部对齐。

align_baseline, 表示与文字内容的基线对齐

imagespan span = new imagespan(tvdrawable, imagespan.align_baseline);

2、setspan()方法

public void setspan(object what, int start, int end, int flags) {
        super.setspan(what, start, end, flags);
    }

what传入各种span类型的实例; 
startend标记要替代的文字内容的范围; 
flags是用来标识在span范围内的文本前后输入新的字符时是否把它们也应用这个效果,它有如下几个:

spanned.span_exclusive_exclusive、

spanned.span_inclusive_exclusive、

spanned.span_exclusive_inclusive、

spanned.span_inclusive_inclusive

inclusive表示应用该效果,exclusive表示不应用该效果,如spanned.span_inclusive_exclusive表示对前面的文字应用该效果,而对后面的文字不应用该效果。

 

坑:

1、既然imagespan只带有两个对齐方式,那我们需要自己实现居中对齐:

class myimagespan extends imagespan {

        public static final int align_center = 2;

        public myimagespan(drawable d, int verticalalignment) {
            super(d, verticalalignment);
        }

        @override
        public void draw(canvas canvas, charsequence text, int start, int end, float x, int top, int y, int bottom, paint paint) {
            drawable b = getdrawable();
            canvas.save();

            paint.fontmetricsint fm = paint.getfontmetricsint();

            //系统默认为align_bottom
            int transy = bottom - b.getbounds().bottom;
            if (mverticalalignment == align_baseline) {
                transy -= fm.descent;
            } else {
                transy = ((y + fm.descent + y + fm.ascent) / 2
                        - b.getbounds().bottom / 2);
            }
            canvas.translate(x, transy);
            b.draw(canvas);
            canvas.restore();
        }

        @override
        public int getsize(paint paint, charsequence text, int start, int end, paint.fontmetricsint fm) {
            drawable b = getdrawable();
            rect rect = b.getbounds();
            if (fm != null) {
                paint.fontmetricsint painfm = paint.getfontmetricsint();
                int fontheight = (painfm.bottom - painfm.top);
                int drheight = rect.bottom - rect.top;

                int top = drheight / 2 - fontheight / 4;
                int bottom = drheight / 2 + fontheight / 4;

                fm.ascent = -bottom;
                fm.top = -bottom;
                fm.bottom = top;
                fm.descent = top;
            }
            return rect.right;
        }
    }

 为何上面的自定义能够实现居中对齐呢?首先要了解paint.fontmetrics。

请看另一篇博客:https://www.cnblogs.com/tangzh/p/8692910.html

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网