kotlin Android TextView显示部分文本,实现全文/展开和收起功能
时间: 2023-12-03 19:46:39 浏览: 230
可以使用以下代码实现TextView部分文本显示和展开/收起功能:
```kotlin
class ExpandableTextView(context: Context, attrs: AttributeSet?) : TextView(context, attrs) {
private var isExpanded: Boolean = false
private var collapsedMaxLines: Int = 2
init {
// 设置TextView默认的最大行数
maxLines = collapsedMaxLines
// 设置TextView默认的Ellipsize
ellipsize = TextUtils.TruncateAt.END
// 设置TextView点击事件
setOnClickListener {
toggle()
}
}
/**
* 设置TextView默认的最大行数
*/
fun setCollapsedMaxLines(maxLines: Int) {
this.collapsedMaxLines = maxLines
this.maxLines = maxLines
}
/**
* 切换TextView的展开/收起状态
*/
private fun toggle() {
isExpanded = !isExpanded
setText(if (isExpanded) getFullText() else getCollapsedText())
// 将TextView改为可聚焦状态,以便展开/收起时接收触摸事件
isFocusable = true
isFocusableInTouchMode = true
}
/**
* 获取TextView展开状态下的完整文本
*/
private fun getFullText(): CharSequence {
val text = text
movementMethod = LinkMovementMethod.getInstance()
return text
}
/**
* 获取TextView收起状态下的文本
*/
private fun getCollapsedText(): CharSequence {
val text = text
val layout = layout ?: return text
movementMethod = LinkMovementMethod.getInstance()
val end = layout.getLineEnd(collapsedMaxLines - 1)
val ellipsis = "..."
val textTrimmed = text.subSequence(0, end)
val lastSpace = textTrimmed.lastIndexOf(' ')
val trimmedLength = textTrimmed.length
return if (lastSpace == -1 || trimmedLength <= end - ellipsis.length) {
"$textTrimmed$ellipsis"
} else {
val index = if (lastSpace + ellipsis.length > end) lastSpace else end - ellipsis.length
"${textTrimmed.subSequence(0, index)}$ellipsis"
}
}
/**
* 保存TextView的状态
*/
override fun onSaveInstanceState(): Parcelable? {
val superState = super.onSaveInstanceState()
return SavedState(superState).apply {
isExpanded = this@ExpandableTextView.isExpanded
}
}
/**
* 恢复TextView的状态
*/
override fun onRestoreInstanceState(state: Parcelable?) {
var savedState = state
if (savedState is SavedState) {
isExpanded = savedState.isExpanded
super.onRestoreInstanceState(savedState.superState)
setText(if (isExpanded) getFullText() else getCollapsedText())
} else {
super.onRestoreInstanceState(savedState)
}
}
private class SavedState : BaseSavedState {
var isExpanded: Boolean = false
constructor(superState: Parcelable?) : super(superState)
constructor(source: Parcel) : super(source) {
isExpanded = source.readInt() == 1
}
override fun writeToParcel(out: Parcel, flags: Int) {
super.writeToParcel(out, flags)
out.writeInt(if (isExpanded) 1 else 0)
}
companion object {
@JvmField
val CREATOR = object : Parcelable.Creator<SavedState> {
override fun createFromParcel(source: Parcel): SavedState {
return SavedState(source)
}
override fun newArray(size: Int): Array<SavedState?> {
return arrayOfNulls(size)
}
}
}
}
}
```
使用方法:
在布局文件中使用该自定义TextView:
```xml
<com.example.ExpandableTextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/lorem_ipsum" />
```
在代码中设置TextView的最大行数和展开/收起状态:
```kotlin
val tvContent = findViewById<ExpandableTextView>(R.id.tv_content)
tvContent.setCollapsedMaxLines(2) // 设置收起状态下的最大行数
tvContent.text = resources.getString(R.string.lorem_ipsum) // 设置TextView的文本
```
如果需要在RecyclerView中使用该自定义TextView,可以在Adapter中设置TextView的展开/收起状态:
```kotlin
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = itemList[position]
holder.itemView.apply {
tvContent.setCollapsedMaxLines(2) // 设置收起状态下的最大行数
tvContent.text = item.text // 设置TextView的文本
tvContent.isExpanded = item.isExpanded // 设置TextView的展开/收起状态
}
}
```
阅读全文