Ellipsize对于具有任意最大高度的多行TextView无法正常工作

DPR*_*DPR 19 android ellipsis multiline textview

我有一个TextView未知的最大高度,这取决于设备的DPI /屏幕分辨率.因此,例如,在on和MDPI设备上,此最大高度可以一次只显示2行,这个值可以增加到未定义的数字.

我的问题与ellipsize功能有关.假设某个设备允许显示4行.如果我手动设置最大行数,就像这样......

<TextView
    android:id="@+id/some_id"
    android:layout_width="fill_parent"
    android:layout_height="0dip"
    android:ellipsize="end" 
    android:maxLines="4"
    android:singleLine="false"
    android:layout_weight="1"
    android:gravity="center_vertical"
    android:text="This is some really really really really really long text"
    android:textSize="15sp" />
Run Code Online (Sandbox Code Playgroud)

......一切正常.如果文本不合适,则在第四行的末尾添加省略号,如下所示:

This is some
really really
really really
really long...
Run Code Online (Sandbox Code Playgroud)

但我宁愿将行数设置为静态变量,因为我更愿意包括对DPI /屏幕分辨率的任何组合的支持.因此,如果我删除maxLines省略号不再在第四行正确显示,则显示文本的不完整部分:

This is some
really really
really really
really long
Run Code Online (Sandbox Code Playgroud)

如果我略微增加TextView大小,我可以看到文本的其余部分仍在"另一个"后面Views.设置变量maxHeight似乎也不起作用.

我真的无法找到解决这个问题的方法.有任何想法吗?如果它有帮助,我只使用Android v4.0.3及更高版本(API级别15).

Mat*_*ers 30

计算有多少行融入TextViewTextView#getHeight()TextView#getLineHeight().然后打电话TextView#setMaxLines().

ViewTreeObserver observer = textView.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        int maxLines = (int) textView.getHeight()
                / textView.getLineHeight();
        textView.setMaxLines(maxLines);
        textView.getViewTreeObserver().removeGlobalOnLayoutListener(
                this);
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 注意:线高可能会有所不同!因此getLineHeight方法不会像预期的那样工作.例如,当使用spannables使字体在文本的特定部分中变大时,可能会发生这种情况. (2认同)

Joh*_*ang 6

接受的答案在API 27之前都可以很好地工作。但是,从API 28开始,如果未设置行高(通过以下方法之一),默认情况下 Android 会在行之间添加额外的间距,但不会在最后一行之后添加额外的间距。

  1. 在布局 XML 中设置属性android:lineHeight=...文档)
  2. 调用textView.setLineHeight(...)您的源代码。

为了找出 API 28 及更高版本的新行高,我使用了textView.getLineBounds().

科特林

val observer = textView?.viewTreeObserver
observer?.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
    override fun onGlobalLayout() {
        textView?.let { view ->
            val lineHeight: Int
            lineHeight = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                val bounds = Rect()
                textView.getLineBounds(0, bounds)
                bounds.bottom - bounds.top
            } else {
                textView.lineHeight
            }
            val maxLines = textView.height / lineHeight
            textView.maxLines = maxLines
            textView.viewTreeObserver.removeOnGlobalLayoutListener(this)
        }
    }
})
Run Code Online (Sandbox Code Playgroud)

安卓Java

ViewTreeObserver observer = textView.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        int lineHeight = textView.getLineHeight();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            Rect bounds = new Rect();
            textView.getLineBounds(0, bounds);
            lineHeight = bounds.bottom - bounds.top;
        }
        int maxLines = (int) textView.getHeight() / lineHeight;
        textView.setMaxLines(maxLines);
        textView.getViewTreeObserver().removeGlobalOnLayoutListener(
            this);
    }
});
Run Code Online (Sandbox Code Playgroud)