Android 支持展开收起的TextView

✏️ 丨 Android 支持展开收起的TextView

1. 需求如下:

近期需要做一个长文本展开收起的功能,当文本内容超过两行,显示展示按钮,点击展开按钮显示全部内容,当文本内容未超过两行时,不显示展示按钮。

2. 实现效果展示

效果图

3. 封装的工具类

/**
 * Desc 支持展开收起的TextView
 * Author ZY
 * Date 2021/10/10 10:30
 */
class ExpandTextView(var context: Context) {

    // 默认展示行数,超过多少行隐藏
    private var maxLine: Int = 2

    // 文本左右边距总合
    private var margin: Int = 0

    // 展开、收起文本颜色
    private var colorStr: String = "#0079e2"

    // 展开显示文本
    private var expandStr: String = "展开"

    // 收起显示文本
    private var foldStr: String = "收起"

    fun setMaxLine(maxLine: Int): ExpandTextView {
        this.maxLine = maxLine
        return this
    }

    fun setMargin(margin: Int): ExpandTextView {
        this.margin = margin
        return this
    }

    fun setColorStr(colorStr: String): ExpandTextView {
        this.colorStr = colorStr
        return this
    }

    fun setFoldStr(foldStr: String): ExpandTextView {
        this.foldStr = foldStr
        return this
    }

    fun setExpandStr(expandStr: String): ExpandTextView {
        this.expandStr = expandStr
        return this
    }

    fun show(expandTextView: TextView, content: String) {

        // 裁剪函数来去除前导空格
        expandTextView.text = content.trimIndent()

        // 获取TextView的画笔对象
        val paint = expandTextView.paint

        // 每行文本布局宽度: 屏幕宽度 - 左右边距
        val width = context.resources.displayMetrics.widthPixels - context.resources.getDimension(margin).toInt()

        val fontColor = ForegroundColorSpan(Color.parseColor(colorStr))
        // 实例化StaticLayout
        val staticLayout = StaticLayout(content, paint, width, Layout.Alignment.ALIGN_NORMAL, 1f, 0f, false)
        // 判断content行数是否超过最大限制行数
        if (staticLayout.lineCount > maxLine) {
            /**
             * 展开后的文本内容
             */
            val str = ("$content\t\t$foldStr")
            val expandSpanStr = SpannableString(str)
            expandSpanStr.setSpan(fontColor, str.length - 2, str.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
            //获取最后一个文字的下标
            val index = staticLayout.getLineStart(maxLine) - 1

            /**
             * 收起后的文本内容
             */
            val str2 = ("${content.substring(0, index - 2)}...$expandStr")
            val foldSpanStr = SpannableString(str2)
            foldSpanStr.setSpan(fontColor, str2.length - 2, str2.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
            //设置收起后的文本内容
            expandTextView.text = foldSpanStr
            expandTextView.setOnClickListener {
                if (expandTextView.isSelected) { //收起的状态
                    expandTextView.text = expandSpanStr
                    expandTextView.isSelected = false
                } else { //展开的状态
                    expandTextView.text = foldSpanStr
                    expandTextView.isSelected = true
                }
            }
            //设成选中状态 true收起状态,false展示状态
            expandTextView.isSelected = true
        } else {
            //未超过最大限制行数,直接设置文本
            expandTextView.text = content
            expandTextView.setOnClickListener(null)
        }
    }
}

4. 调用方式如下

采用链式调用方式,可动态配置默认显示行数、提示文字颜色、边距

     override fun onCreate(savedInstanceState: Bundle?) {
        val content = "日前,河南郑州市金水区税务局运用大数据实现信息系统自动提取数据,加大文娱领域从业人员税收征管力度,追征一名网红的662.44万元税款收入国库。笔者看来,网红补税释放了两个信号。一是新技术会更多应用在税收征管中,实现应缴尽缴。二是某些领域行业还存在税收征管盲区,需要加大征管力度。加大对明星、网红的税收征管力度,是国家加大对高收入群体税收监管力度的一个缩影,这一举措有助于税负公平,有利于调节收入分配,促进社会公平。社会公众关注高收入群体缴税情况,也是追求责任义务对等公平的体现。"
        val ex  = ExpandTextView(this)
            .setMaxLine(2)
            .setMargin(R.dimen.dp_60)
            .setColorStr("#346CE9")
            .setFoldStr("查看全部")
            .setExpandStr("展开")
			.show(tv_remark, content)

如果显示多个展开收起组件,可以复用设置的属性

     override fun onCreate(savedInstanceState: Bundle?) {

		// 情景一:文本长度超过两行
        val content = "日前,河南郑州市金水区税务局运用大数据实现信息系统自动提取数据,加大文娱领域从业人员税收征管力度,追征一名网红的662.44万元税款收入国库。笔者看来,网红补税释放了两个信号。一是新技术会更多应用在税收征管中,实现应缴尽缴。二是某些领域行业还存在税收征管盲区,需要加大征管力度。加大对明星、网红的税收征管力度,是国家加大对高收入群体税收监管力度的一个缩影,这一举措有助于税负公平,有利于调节收入分配,促进社会公平。社会公众关注高收入群体缴税情况,也是追求责任义务对等公平的体现。"

		// 情景二:当文本长度不足两行
        val content2 = "情景二:当文本长度不足两行:"

        val content3 ="据公开消息,北方多地经历暴雪、降温。进入11月份,全省供暖工作陆续启动,为此,沈阳局集团公司充分发挥煤炭运输主通道作用,以保发电供热用煤为重点。值得注意的是,今年以来国际市场能源价格大幅上涨,国内电力、煤炭供需持续偏紧,大家都担心煤电供应问题。"

        val ex  = ExpandTextView(this)
            .setMaxLine(2)
            .setMargin(R.dimen.dp_60)
            .setColorStr("#346CE9")

        ex.show(tv_remark, content)
        ex.show(tv_remark2, content2)
        ex.show(tv_remark3, content3)
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值