?目前的需求是:
文字如果超出x行则在尾部显示 “全部”,点击展开全部文字,再点击收缩文字,不够三行则正常展示,效果如图
大概思路就是: 计算出x行文字总共需要占用多大空间(即 view.width * x),? 这个空间减去尾部文字占用的空间,就是x行可显示字数的空间,再将这些字提取出来(直接使用TextUtils来处理),最后做拼接就ok了
fun setMoreString(
textView: TextView,
moreString: CharSequence, // 尾部文字,用charSequence可拓展样式
shrink: Boolean, // 是否收缩
shrinkLine: Int, // 超出此行折叠显示
contentText: String, // 原文本内容
moreColor: Int, // 更多文字的颜色
clickMoreAction: BindingCommand<Boolean> // 文字点击事件
) {
textView.apply {
post {
// shrinkLine 行能显示的最大宽度
val avbLength = (width - paddingStart - paddingEnd) * shrinkLine
// 原文本需要的宽度
var contentWid = paint.measureText(contentText)
// 未铺满行数 直接设置原文本
if (avbLength > contentWid) {
text = contentText
} else {
// 尾部文字的width
var moreWid = paint.measureText(moreString, 0, moreString.length)
// 得到已收缩的文本内容 用于填充TextView
val shrinkString = TextUtils.ellipsize(
contentText,
paint,
avbLength - moreWid,
TextUtils.TruncateAt.END
)
SpanUtils.with(this)
.append(
if (shrink) {
shrinkString
} else {
contentText
}
)
.append(" ")
.append(moreString)
.setClickSpan(object : ClickableSpan() {
override fun onClick(widget: View) {
// 我此处的点击事件交由外部处理 , 不同的使用场景可以自己灵活处理
clickMoreAction.execute(!shrink)
}
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = moreColor
ds.isUnderlineText = false
}
})
.create()
}
}
}
}
这个方法会存在的问题: 换行符、 英文单词等太长自动换行,导致某一行尾部出现空白,这些情况下计算出的宽度就不准确了
|