如何在Android TextView中使用自定义省略号
我有一个maxlines=3的TextView,我想使用我自己的省略号,而不是如何在Android TextView中使用自定义省略号,android,textview,ellipsis,Android,Textview,Ellipsis,我有一个maxlines=3的TextView,我想使用我自己的省略号,而不是 "Lore ipsum ..." 我需要 "Lore ipsum ... [See more]" 为了给用户一个提示,点击视图将展开全文 可能吗 我正在考虑检查TextView是否有省略号,在这种情况下,添加文本“[查看更多]”,然后在前面设置省略号,但我找不到这样做的方法 也许如果我找到了文本被剪切的位置,我可以禁用省略号并生成一个子字符串,然后添加“…[查看更多]”,但我仍然不知道如何获得该位置。我最终以这种
"Lore ipsum ..."
我需要
"Lore ipsum ... [See more]"
为了给用户一个提示,点击视图将展开全文
可能吗
我正在考虑检查TextView是否有省略号,在这种情况下,添加文本“[查看更多]”,然后在前面设置省略号,但我找不到这样做的方法
也许如果我找到了文本被剪切的位置,我可以禁用省略号并生成一个子字符串,然后添加“…[查看更多]”,但我仍然不知道如何获得该位置。我最终以这种方式管理它(可能不是最好的方式):
我认为@jmhostalet的答案会降低性能(特别是在处理列表和大量文本视图时),因为文本视图会多次绘制文本。我创建了一个自定义文本视图,它在
onMeasure()
中解决了这个问题,因此只绘制一次文本
我最初在这里发布了我的答案:
这里是到repo的链接:@George@jmhostalet我在我的回收器视图中这样做,它降低了整个性能
ViewTreeObserver vto = previewContent.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
try {
Layout layout = previewContent.getLayout();
int index1 = layout.getLineStart(previewContent.getMaxLines());
if (index1 > 10 && index1 < ab.getPreviewContent().length()) {
String s =
previewContent.getText().toString().substring(0, index1 - 10);
previewContent
.setText(Html.fromHtml(
s + "<font color='#DC5530'>...और पढ़ें</font>"));
}
return true;
}catch (Exception e)
{
Crashlytics.logException(e);
}
return true;
}
});`
ViewTreeObserver vto=previewContent.getViewTreeObserver();
addOnPreDrawListener(新的ViewTreeObserver.OnPreDrawListener(){
@凌驾
公共布尔onPreDraw(){
试一试{
Layout Layout=previewContent.getLayout();
int index1=layout.getLineStart(previewContent.getMaxLines());
if(index1>10&&index1
这里有一个使用Kotlin扩展的好方法。
注意,我们需要等待视图布局,然后才能测量和附加后缀
在TextViewExtensions.kt中
fun TextView.setEllipsizedSuffix(maxLines: Int, suffix: String) {
addOnLayoutChangeListener(object: View.OnLayoutChangeListener {
override fun onLayoutChange(v: View?, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int) {
val allText = text.toString()
var newText = allText
val tvWidth = width
val textSize = textSize
if(!TextUtil.textHasEllipsized(newText, tvWidth, textSize, maxLines)) return
while (TextUtil.textHasEllipsized(newText, tvWidth, textSize, maxLines)) {
newText = newText.substring(0, newText.length - 1).trim()
}
//now replace the last few chars with the suffix if we can
val endIndex = newText.length - suffix.length - 1 //minus 1 just to make sure we have enough room
if(endIndex > 0) {
newText = "${newText.substring(0, endIndex).trim()}$suffix"
}
text = newText
removeOnLayoutChangeListener(this)
}
})
}
fun textHasEllipsized(text: String, tvWidth: Int, textSize: Float, maxLines: Int): Boolean {
val paint = Paint()
paint.textSize = textSize
val size = paint.measureText(text).toInt()
return size > tvWidth * maxLines
}
在TextUtil.kt中
fun TextView.setEllipsizedSuffix(maxLines: Int, suffix: String) {
addOnLayoutChangeListener(object: View.OnLayoutChangeListener {
override fun onLayoutChange(v: View?, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int) {
val allText = text.toString()
var newText = allText
val tvWidth = width
val textSize = textSize
if(!TextUtil.textHasEllipsized(newText, tvWidth, textSize, maxLines)) return
while (TextUtil.textHasEllipsized(newText, tvWidth, textSize, maxLines)) {
newText = newText.substring(0, newText.length - 1).trim()
}
//now replace the last few chars with the suffix if we can
val endIndex = newText.length - suffix.length - 1 //minus 1 just to make sure we have enough room
if(endIndex > 0) {
newText = "${newText.substring(0, endIndex).trim()}$suffix"
}
text = newText
removeOnLayoutChangeListener(this)
}
})
}
fun textHasEllipsized(text: String, tvWidth: Int, textSize: Float, maxLines: Int): Boolean {
val paint = Paint()
paint.textSize = textSize
val size = paint.measureText(text).toInt()
return size > tvWidth * maxLines
}
那么实际上是这样使用的
myTextView.setEllipsizedSuffix(2,“…请参阅更多”)
注意:如果文本来自服务器,并且可能有新行字符,则可以使用此方法确定文本是否已省略
fun textHasEllipsized(text: String, tvWidth: Int, textSize: Float, maxLines: Int): Boolean {
val paint = Paint()
paint.textSize = textSize
val size = paint.measureText(text).toInt()
val newLineChars = StringUtils.countMatches(text, "\n")
return size > tvWidth * maxLines || newLineChars >= maxLines
}
StringUtils
来自实现“org.apache.commons:commons-lang3:3.4”
以下是Kotlin的解决方案
yourTextView.post{}是必需的,因为textview在呈现之前不会被省略
val customSuffix = "... [See more]"
yourTextView.post {
if (yourTextView.layout.getEllipsisStart(-1) != -1) {
val newText = yourTextView.text.removeRange(
yourTextView.layout.getEllipsisStart(-1) - customSuffix.length, yourTextView.text.length
)
yourTextView.text = String.format("%s%s", newText, customSuffix)
}
}
请参阅l.getEllipsisStart()
而不是像ellipsis=“…”;
中那样使用三个点,您应该使用水平省略号字符(…;entity->…
)textView.getLayout()返回null Android使用TextUtils.省略号\u NORMAL[0]
用于标准省略号,解析为'\u2026'
。这可以在TextView间接使用的方法中找到。已尝试在recyclerView.TextView.getLayout()中使用此方法返回null。是否需要进行任何修改以使其对回收器/列表视图有用?如果getLayout使用null,请使用ViewTreeObserver.OnGlobalLayoutListener.yup我在回收器视图中执行了此操作。这会降低整个性能,请确保将yourTextView
替换为您试图省略的文本视图。是的,我正在执行此操作使用文本视图。但在handler@Xenolion我没有针对多行测试它,但我看不出它不起作用的任何原因。我想到的原因是布局。getEllipsisStart(line)为特定行提供省略号开头,但不是为所有文本提供省略号开头!可能是。我会说试试看。