TextView行高的问题

上文中提及了自定义选择背景,自定义后如果不是像原生一样填充满选择区域的话,例如每行有空隙,就会发现另一个问题,textview每行的高度居然有差异。具体来说是分为首行,尾行,单行,中间行四种。

在Android TextView行间距解析中其实已经解释了这种现象的原因。

StaticLayout.java

private int out(CharSequence text, int start, int end,
                  int above, int below, int top, int bottom, int v,
                  float spacingmult, float spacingadd,
                  LineHeightSpan[] chooseHt, int[] chooseHtv,
                  Paint.FontMetricsInt fm, int flags,
                  boolean needMultiply, byte[] chdirs, int dir,
                  boolean easy, int bufEnd, boolean includePad,
                  boolean trackPad, char[] chs,
                  float[] widths, int widthStart, TextUtils.TruncateAt ellipsize,
                  float ellipsisWidth, float textWidth,
                  TextPaint paint, boolean moreChars) {
    …
    if (firstLine) {
        if (trackPad) {
            mTopPadding = top - above;
        }

        if (includePad) {
            above = top;
        }
    }    

    int extra;

    if (lastLine) {
        if (trackPad) {
            mBottomPadding = bottom - below;
        }

        if (includePad) {
            below = bottom;
        }
    }
    … 
}

out方法是StaticLayout中布局完毕后初始化各种成员变量的方法。

这里的includePad就是TextView的setIncludeFontPadding方法传入的值或者xml中定义的includefontpadding属性,默认是true。可以看出如果是true的话,below就会等于bottom,above就会等于top。这里的below其实就是descent,above就是ascent,见Android绘制文本基本概念之- top, bottom, ascent, descent, baseline。如果是单行当然就同时满足首行和尾行的概念,会更特殊。这样就解释了四种差别的由来。通过分析,可以看出最简单的方法是setIncludeFontPadding(false)就能解决行高差异。

但是问题还没有结束,尾行还有更特殊的性质,就是行间距的影响,android默认的行间距其实就是在行的bottom上加一段距离,但是尾行除外,因为按照正常思维来说尾行已经结束,后续无内容,所以无需再留间距。这对行高有重大影响啊。

问题到这里结束了吗,no,不要太天真。产商会修改TextView相关源码,例如我手里的魅蓝手机,尾行依然是有行间距的,多惊喜啊,还得针对这个做适配。


你可能感兴趣的:(android)