【发布时间】:2014-05-13 02:44:46
【问题描述】:
这个问题可能和this one一样,但由于它的答案都没有真正解决问题,我再问一遍。
我的应用有一个 TextView,它偶尔会显示很长的 URL。出于美学原因(并且由于 URL 不包含空格),理想的行为是在跳到下一行之前完全填满每一行,如下所示:
|http://www.domain.com/som|
|ething/otherthing/foobar/|
|helloworld |
相反,URL 在条附近被破坏,就好像它们是空格一样。
|http://www.domain.com/ |
|something/otherthing/ |
|foobar/helloworld |
我尝试扩展 TextView 类并添加 breakManually 方法的修改版本 (found here) 来欺骗 TextView 并执行我需要的操作,调用它onSizeChanged(被覆盖)。它工作正常,除了 TextView 在 ListView 内。当此自定义 TextView 被滚动隐藏并返回时,它的内容会回到原来的破坏行为,因为视图在没有调用 onSizeChanged 的情况下被重新绘制。
我能够通过在 onDraw 中调用 breakManually 来解决这个问题。这始终呈现预期的行为,但性能成本很高:因为每当滚动 ListView 和 breakManually 时都会调用 onDraw em> 方法并不完全是“轻量级”,即使在高端四核设备上,滚动也会变得无法接受。
下一步是爬取TextView source code,试图弄清楚它在哪里以及如何拆分文本,并希望覆盖它。这是一个彻底的失败。我(一个新手)花了一整天毫无结果地看着我几乎无法理解的代码。
这把我带到了这里。有人可以为我指出我应该覆盖的正确方向(假设它是可能的)吗?或者也许有更简单的方法来实现我想要的?
这是我提到的 breakManually 方法。由于使用了 getWidth(),它仅在测量视图后调用才有效。
private CharSequence breakManually (CharSequence text) {
int width = getWidth() - getPaddingLeft() - getPaddingRight();
// Can't break with a width of 0.
if (width == 0) return text;
Editable editable = new SpannableStringBuilder(text);
//creates an array with the width of each character
float[] widths = new float[editable.length()];
Paint p = getPaint();
p.getTextWidths(editable.toString(), widths);
float currentWidth = 0.0f;
int position = 0;
int insertCount = 0;
int initialLength = editable.length();
while (position < initialLength) {
currentWidth += widths[position];
char curChar = editable.charAt(position + insertCount);
if (curChar == '\n') {
currentWidth = 0.0f;
} else if (currentWidth > width) {
editable.insert(position + insertCount , "\n");
insertCount++;
currentWidth = widths[position];
}
position++;
}
return editable.toString();
}
感谢所有阅读本文的人,感谢您的宝贵时间。
【问题讨论】:
-
与其关闭这个(这是一个更好的问题),我建议如果有答案,记得关闭stackoverflow.com/questions/21094349/…
-
关于建议的问题 (stackoverflow.com/questions/4204295/…),其接受的答案基本上就是我在第 3 段中描述的内容。如果 TextView 不移动,它可以正常工作,但一旦在 ListView 中出现异常。我的意图是重写负责拆分文本的任何方法,使自定义 TextView 从一开始就按预期呈现,并且在绘制视图后不更改其内容。
标签: android textview word-wrap