【问题标题】:Format first line of a multiline TextView in Android在Android中格式化多行TextView的第一行
【发布时间】:2017-10-13 04:24:35
【问题描述】:

我有多行 TextView,我只需要格式化它的单行。由于字体大小和样式是动态的,我需要它来自动格式化“第一行”。

这个TextView显示的是一个没有换行符的字符串,它是自动换行的,我需要格式化第一行换行。

请查看附件图片:

【问题讨论】:

  • html 文本 ddnt 工作?
  • @MohammedAtif,不,因为文本是动态的,我不知道第一行有哪些单词,所以我可以在 HTML 中设置它们的样式
  • 某种意义上的动态文本?是随机来源还是文本是由您自己团队的某个人生成的?
  • 那么如何用动态文本定义第一行,这就是解决方案。
  • @MohammedAtif 这不是随机的,它是一张卡片的标题,我想让第一行(不管它是什么)加粗

标签: android textview format render


【解决方案1】:

我找到了使用 StaticLayout 的解决方案。

private TextView tvTitle; //bold title with maxLines = 1
private TextView tvText; //the rest of the text

//initialize views, etc...

private void showText(@Nonnull String text) {
    tvTitle.setText(text);

    tvTitle.post(() -> {
        String ellipsizedText = getEllipsizedText(text, tvTitle);
        tvText.setText(ellipsizedText);
    });
}

private static String getEllipsizedText(String text, TextView textView) {
    StaticLayout staticLayout = getStaticLayout(text,
            textView.getPaint(),
            textView.getWidth(),
            1,
            null);
    return text.substring(staticLayout.getLineEnd(0));
}

private static StaticLayout getStaticLayout(CharSequence text,
                                            TextPaint paint,
                                            int width,
                                            int maxLines,
                                            TextUtils.TruncateAt ellipsize) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        return StaticLayout.Builder.obtain(text, 0, text.length(), paint, width)
                .setTextDirection(TextDirectionHeuristics.FIRSTSTRONG_LTR)
                .setAlignment(Layout.Alignment.ALIGN_NORMAL)
                .setLineSpacing(0f, 1f)
                .setIncludePad(false)
                .setEllipsize(ellipsize)
                .setEllipsizedWidth(width)
                .setMaxLines(maxLines)
                .build();
    } else {
        return new StaticLayout(text,
                paint,
                width,
                Layout.Alignment.ALIGN_NORMAL,
                1f,
                0f,
                false);
    }
}

【讨论】:

    【解决方案2】:

    来自@HiteshGehlot 的回答:

    myTextView.setText(Html.fromHtml("<b>This is a normal</b><br>second line<br>third line"));
    

    但由于您的系统是动态的,因此这不是一个好方法。此代码生成适当的 HTML:

    String lines[] = string.split("\\n");
    String fl = String.format(Locale.ENGLISH, "<b>%s</b><br>", lines[0]);
    StringBuilder sb = new StringBuilder();
    sb.append(fl);
    for(int i = 1; i < lines.length; i++){
        sb.append(lines[i] + "<br>");
    }
    String finalProduct = sb.toString();
    

    然后:

    myTextView.setText(Html.fromHtml(finalProduct));
    

    这应该为第一行动态创建 HTML 标记


    解释

    这是对先前答案的改进。使用 HTML,第一行被格式化为粗体。

    使用正则表达式,我们用换行符(\n)分割所有行。数组中的第一个字符串是第一行,而其余的对于格式化并不重要。所以首先我们附加第一行,然后添加其余的。 for 循环从 1 开始,因为 0 是第一行。

    注意

    如果您确实动态地中断文本,则将该字符串传递给上述方法。我在这里介绍的方法使用这些换行符来确定哪一行在哪里,以便能够将第一行设置为粗体

    【讨论】:

      【解决方案3】:

      试试这个:

      myTextView.setText(Html.fromHtml("<b>This is a normal</b><br>second line<br>third line"));
      

      【讨论】:

      • 如果您的文本是动态的,只需传递包含第一行、第二行的字符串对象...
      • 换行是动态完成的,取决于字体大小!
      【解决方案4】:

      只需使用另一个 TextView。 文本视图 1、文本视图 2、文本视图 3。 并将 TextView1 设置为粗体。

      【讨论】:

      • 换行是动态完成的,取决于字体大小!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-04
      • 2021-03-27
      • 2020-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多