24

我有TextView一个未知的最大高度,这取决于设备的 DPI/屏幕分辨率。因此,例如,在 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" />

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

This is some
really really
really really
really long...

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

This is some
really really
really really
really long

如果我稍微增加TextView大小,我可以看到其余的文本仍然被绘制在另一个“后面” Views。设置变量maxHeight似乎也不起作用。

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

4

2 回答 2

37

计算有多少行适合TextViewwithTextView#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);
    }
});
于 2013-01-05T19:09:10.767 回答
4

接受的答案适用于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)
        }
    }
})

安卓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);
    }
});
于 2019-10-22T01:52:12.943 回答