【问题标题】:Wrapping a block of text if the line that textView sits on gets too long如果 textView 所在的行太长,则换行一段文本
【发布时间】:2015-03-15 09:48:23
【问题描述】:

我正在寻找满足此要求的最佳方法。如果在其他地方得到了回答,我深表歉意,我找不到解决这个看似简单的问题的方法。

列表中有一行文本,如下所示:

项目的标题 -(5 个项目)

如果项目的标题变得太长,那么它会换行,这是预期的。但是,它不应该包含在“5”和“items”之间。如果它需要换行,那么整个“(5 个项目)”应该换行到下一行。并且标题的文字应该是省略号。

我似乎无法找到一种方法来创建适用于此的布局。

【问题讨论】:

标签: android xml android-layout layout


【解决方案1】:

This 可能会有所帮助。您可以使用android:ellipsize 属性定义要截断文本的哪一部分。

在你的情况下,根据链接的答案,我会使用 android:ellipsize="middle"android:ellipsize="marquee",这样可以阅读文本幻灯片。

虽然这实际上并不能满足您的要求(项目数量自动进入第二行),但我认为这可能是一个更好的解决方案。

查看官方信息here


我想到的另一件事是使用两个不同的TextViews,一个用于标题,另一个(右对齐?)用于项目计数。我会把android:ellipsize="end" 给第一个,android:layout_width="wrap_content" 给后者。


您还可以在标题下方添加一个计数 TextView,如果有足够的空间,它会附加到标题。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/container"
    android:orientation="vertical" >

    <TextView android:id="@+id/text1"
        android:text="a very very very long title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ellipsize="end" />


    <TextView android:id="@+id/text2"
        android:text="(5 items)"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

您可以在代码中检查宽度:

View container = findViewById(R.id.container);
TextView tv1 = (TextView) findViewById(R.id.text1);
TextView tv2 = (TextView) findViewById(R.id.text2);


String HEADER = tv1.getText();
String COUNT = tv2.getText();

int widthHeader = tv1.getWidth();
int widthCount = tv1.getWidth();
int widthAvailable = container.getWidth();

if (widthAvailable - widthHeader > widthCount) {
    tv1.setText(HEADER + " - " + COUNT);
    tv2.setText("");
}

【讨论】:

  • 我同意有比我的问题中提出的方式更好的解决方案。我已经为客户提供了其他几个选项,但他们对想要按照规定的方式提出了一些反对意见。在我以“无法完成”的方式回到他们面前之前,我希望找到一个适合他们想要的解决方案。
【解决方案2】:

TextUtils 类有一个名为 ellipsize 的方法

public static CharSequence ellipsize (CharSequence text, TextPaint p, floatavail, TextUtils.TruncateAt where) 在 API 级别 1 中添加

如果在给定指定 Paint 的属性的情况下适合指定宽度,则返回原始文本,或者,如果不适合,则返回在指定边缘或中心添加省略号字符的截断副本。

这是我们如何使用它。让我们假设“项目标题 - (5 项目)”是全文,(5 项目) 是后缀,textView 是包含文本的文本视图。

String ellipsizedText = TextUtils.ellipsize(fullText, textView.getPaint(), fullTexViewtWidth ,TextUtils.TruncateAt.END);

现在文本要么被椭圆化,要么不会。我们可以通过检查 ellipsizedText 中是否存在后缀来检查这一点。 如果它是椭圆的(删除了后缀),我们应该再次调用 ellipsize 函数,但这次要减小宽度,因为我们想为后缀字符串保留空间并删除后缀,因为我们是单独添加它的。所以,新的调用将是

ellipsizedText = TextUtils.ellipsize(removedSuffixText, textView.getPaint(), reducedWidth ,TextUtils.TruncateAt.END);

最后我们将textView的文本设置为ellipsizedText+suffix;

我们需要找出几个值

  1. fullTexViewtWidth - 这可能很棘手,因为我们没有为文本视图指定特定的宽度。假设我们将宽度设置为匹配父级,那么我们可以通过视图树观察器来实现它。关注答案here
  2. reducedWidth - 这更加棘手。为了计算这个,我们需要找到后缀占用的宽度,然后从 fullTexViewtWidth 中减去它。 This answer 解释如何查找后缀占用的宽度

    final float densityMultiplier = getContext().getResources().getDisplayMetrics().density; final float scaledPx = 20 * densityMultiplier; paint.setTextSize(scaledPx); final float size = paint.measureText("sample text");

恐怕这只有在 maxLines 为 1 且宽度设置为 textView 的 matchparent 时才有效。

【讨论】:

  • 检查文本是否为椭圆后,您可以将“-”替换为“\n”,并将 textview 中的行数设置为 2。如果不是椭圆,则将其保留为 singleLine ="true" 与原始测试。
【解决方案3】:

从你的问题我可以理解的是

1) It does not matter how long the title text is,it can wrap according to its length.

2) Your text "(5 items)" should not break, it should stays together. What ever
   is the length of your TITLE.

如果以上2点是正确的。那么简单的解决方案就是这样

 Just replace your String "(5 items)"

 String "(5&#160;items)"

注意:

Here, '&#160' is character code of 'SPACE'. This bind's your string as one 
String and stays together.

希望这能解决您的问题。

【讨论】:

  • 对不起,如果我误解了您的问题,请告诉我。
  • 感谢您的尝试,但如果标题太长,它应该变成椭圆形并且只适合一行。如果确实这样做了,那么 (5 items) 部分应该换到下一行。
【解决方案4】:

您是否尝试过包含两个文本视图的相对布局,一个用于标题,另一个用于“标签”?使用左侧的相对布局:

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/container" >

<TextView android:id="@+id/text1"
    android:text="a very very very long title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:toLeftOf="@+id/label" />


<TextView android:id="@+id/label"
    android:text="(5 items)"
    android:singleLine="true"
    android:layout_alignParentRight="true" 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

您也可以使用线性布局权重,这将使文本始终适合某个比例(在本示例中,标题为 80%,标签为 20%):

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weight_sum="100"
android:orientation="horizontal"
android:id="@+id/container" >

<TextView android:id="@+id/text1"
    android:weight="80"
    android:text="a very very very long title"
    android:layout_width="0dp"
    android:layout_height="wrap_content" />


<TextView android:id="@+id/label"
    android:text="(5 items)"
    android:singleLine="true"
    android:weight="20"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

</LinearLayout>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    • 2020-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多