Android 支持展开收起的TextView

Posted 左郁

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)

以上是关于Android 支持展开收起的TextView的主要内容,如果未能解决你的问题,请参考以下文章

Android 支持展开收起的TextView

Android 支持展开收起的TextView

Android 自定义 View-->TextView 的展开 & 收起(文本折叠)

android可滑动收起展开布局

iOS中如何让TextView和TextField控件支持return键收起输入法

Android 自定义View之展开收起的Layout