在StaticLayout上设置最大行

时间:2018-08-27 16:44:14

标签: android

StaticLayout.Builder是API 23中引入的,我希望将目标降低。如何使用StaticLayout的原始构造函数设置最大行数?

参考上的属性似乎都是只读的。

3 个答案:

答案 0 :(得分:2)

在API 22之后的StaticLayout类中,仍然存在一个带有许多参数的隐藏构造函数:

 /**
  * @hide
  * @deprecated Use {@link Builder} instead.
  */
 @Deprecated
 public StaticLayout(CharSequence source, int bufstart, int bufend,
                     TextPaint paint, int outerwidth,
                     Alignment align, TextDirectionHeuristic textDir,
                     float spacingmult, float spacingadd,
                     boolean includepad,
                     TextUtils.TruncateAt ellipsize, int ellipsizedWidth,
                     int maxLines)

如您所见,最后一个参数是最大行数。

答案 1 :(得分:0)

此构造函数是隐藏的,似乎无法将其用于较旧的 API。我什至尝试使用反射设置私有字段 mMaximumVisibleLineCount,但没有运气。但是我找到了一种向后兼容的解决方案,可以省略字符串并创建 StaticLayout 直到 lineCount 返回所需的值。

fun createStaticLayout(text: String, textWidth: Int, maxLines: Int, paint: TextPaint): StaticLayout =
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        StaticLayout.Builder
            .obtain(text, 0, text.length, paint, textWidth)
            .setAlignment(Layout.Alignment.ALIGN_NORMAL)
            .setMaxLines(maxLines)
            .setEllipsize(TextUtils.TruncateAt.END)
            .build()
    } else {
        var layout: StaticLayout? = null
        var maxLength: Int = min(text.length, 200) // Could be adjusted

        do {
            layout = StaticLayout(
                text.ellipsize(maxLength), paint, textWidth,
                Layout.Alignment.ALIGN_NORMAL, 1f, 0f,
                false
            )
            maxLength -= 10
        } while (layout!!.lineCount > maxLines)

        layout
    }

///.....

fun String.ellipsize(
    size: Int,
    ending: Char? = '…'
): String = if (this.isEmpty() || size <= 0) {
    ""
} else if (length <= size) {
    this
} else {
    this.substring(0, max(size - 1, 0)).let {
        if (ending == null) {
            it
        } else {
            it + ending
        }
    }
}


答案 2 :(得分:0)

我发现的唯一方法是使用反射来访问第四个构造函数,该构造函数接受在最后一个参数中设置 maxLines 并且它对我有用:

try {
                Constructor<StaticLayout> constructor = StaticLayout.class.getConstructor(
                        CharSequence.class, int.class, int.class, TextPaint.class, int.class,
                        Layout.Alignment.class, TextDirectionHeuristic.class, float.class, float.class,
                        boolean.class, TextUtils.TruncateAt.class, int.class, int.class
                );
                constructor.setAccessible(true);
                StaticLayout sl = constructor.newInstance(text, 0, text.length(), textPaint, width,
                        aligment, TextDirectionHeuristics.FIRSTSTRONG_LTR, spacingMult, spacingAdd,
                        includePad, TextUtils.TruncateAt.END, width, maxLines);

            } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException exception) {
                Log.d("TAG_APP", Log.getStackTraceString(exception));
            }