在Android中格式化多行TextView的第一行

Posted

技术标签:

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

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

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

请查看附件图片:

【问题讨论】:

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

【讨论】:

换行是动态完成的,取决于字体大小!

以上是关于在Android中格式化多行TextView的第一行的主要内容,如果未能解决你的问题,请参考以下文章

Android 并在 TableRow 的 TextView 中显示多行文本

无法在 Android Studio 中格式化部分 TextView 或 Button 文本

Android中的多行TextView?

Android TextView 多行问题(去掉第二行的gab)

怎么能让TextView的文本显示一行

Android TextView 不会用多行紧紧地拥抱文本,而是坚持使用 maxWidth