Android实现超出固定行数折叠文字“查看全文“、“收起全文“

这篇具有很好参考价值的文章主要介绍了Android实现超出固定行数折叠文字“查看全文“、“收起全文“。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

先上效果图

Android实现超出固定行数折叠文字“查看全文“、“收起全文“,自定义控件,android

分析问题

网上有很多关于这个的代码,实现都过于复杂了,github上甚至还看到一篇文章600多行代码,结果一跑起来全是bug。还是自己写吧!!!
如果我们需要换行的"查看全文"、"收起全文"效果那没什么号说的,因为可以直接用两个TextView然后通过判断超过行数还是没有超过行数来判断显示还是隐藏即可。这没有什么难度,这里我们需要实现同一TextView实现。
要在 TextView 的部分文字上添加颜色和点击事件,您可以使用 SpannableStringClickableSpan 来实现。
为了避免重复代码,那我们肯定是自定义View实现,新建一个ScalingTextView,继承AppCompatTextView

class ScalingTextView(context: Context, attrs: AttributeSet?) :
    AppCompatTextView(context, attrs) {

}

然后我们需要几个参数

<!--一段测试文字-->
<string name="scaling_str">这是一段ScalingTextView的折叠测试文字,测试多行显示的时候是否可以”查看全文“、”收起全文“这个功能是否正常呢,但是这个问题必须要超过两行才行,因此我现在每打的一个字都是在凑字数,你懂了吧!!!</string>

SpannableStringClickableSpan 对象

    private var spannableString: SpannableString? = null

    // 创建 ClickableSpan 对象
    val clickableSpan = object : ClickableSpan() {
        override fun onClick(widget: View) {
            // 在这里处理点击事件
            toggleText()
        }

        override fun updateDrawState(ds: TextPaint) {
            // 设置点击文字的颜色
            ds.color = Color.BLUE
            // 如果不希望点击文字有下划线,可以注释下面这行代码
            ds.isUnderlineText = true
        }
    }
    fun toggleText() {
        if (isCollapsed) {
            // 展开文本
            maxLines = Integer.MAX_VALUE
            isCollapsed = false
        } else {
            // 折叠文本
            maxLines = maxLinesCollapsed
            isCollapsed = true
        }
    }

当然还有些其他便于设置的参数,例如:

    private var maxLinesCollapsed: Int = 2//默认折叠行数
    private var isCollapsed: Boolean = false
    private var mOriginText: String //文本内容
    private @ColorInt var mOriginTextColor: Int//折叠文字颜色
    private val DEFAULT_OPEN_SUFFIX = "查看全文"
    private val DEFAULT_CLOSE_SUFFIX = "收起全文"
    private val ellipsis = "..."

当然这些参数我们需要通过xml里直接配置,不用每次都set一堆方法对吧,所以添加自定义属性

    <declare-styleable name="scaling_text_view">
        <attr name="content_text" format="string"></attr>
        <attr name="content_text_color" format="color"></attr>
    </declare-styleable>

然后获取这几个自定义参数,大家可以自行增加,这里只为演示内容

    init {
        val typedValue = context.obtainStyledAttributes(attrs, R.styleable.scaling_text_view)
        mOriginText = typedValue.getString(R.styleable.scaling_text_view_content_text).toString()
        mOriginTextColor = typedValue.getColor(R.styleable.scaling_text_view_content_text_color,ContextCompat.getColor(context,R.color.themeColor)).toInt()
    }

最后我们如何实现功能呢?我们可以从几个方向去分析:

  • 在文字结尾追加上“...”省略号和 "查看全文""收起全文",这个不难
  • 当超出最大限制行数的时候我们需要截取掉多余内容,并且为“...”省略号和 "查看全文""收起全文"空出位置
  • "查看全文""收起全文"添加颜色
  • 最后为 "查看全文""收起全文"添加点击事件
  • 最后的最后刷新文本内容

那么我们可以重写onMeasure
这里我们用到一个方法getLineEnd

            val lineEndIndex = layout.getLineEnd(maxLinesCollapsed - 1)
            val newText = text.subSequence(
                0, lineEndIndex - ellipsis.length + 1 - DEFAULT_OPEN_SUFFIX.length + 1
            ).toString().trim { it <= ' ' } + ellipsis + DEFAULT_OPEN_SUFFIX

创建SpannableString对象

spannableString = SpannableString(newText);
 //设置点击事件
            spannableString?.setSpan(
                clickableSpan,
                newText.lastIndexOf(DEFAULT_OPEN_SUFFIX),
                newText.lastIndexOf(DEFAULT_OPEN_SUFFIX) + DEFAULT_OPEN_SUFFIX.length,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            //设置文本颜色
            spannableString?.setSpan(
                ForegroundColorSpan(mOriginTextColor),
                newText.lastIndexOf(DEFAULT_OPEN_SUFFIX),
                newText.lastIndexOf(DEFAULT_OPEN_SUFFIX) + DEFAULT_OPEN_SUFFIX.length,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )

最后设置刷新文本

            text = spannableString
            movementMethod = LinkMovementMethod.getInstance()
            super.onMeasure(widthMeasureSpec, heightMeasureSpec)

好了,我们搞定了,完整代码

class ScalingTextView(context: Context, attrs: AttributeSet?) :
    AppCompatTextView(context, attrs) {
    private var maxLinesCollapsed: Int = 2
    private var isCollapsed: Boolean = false
    private val TAG: String = ScalingTextView::class.java.simpleName
    private var mOriginText: String
    private @ColorInt var mOriginTextColor: Int

    private val DEFAULT_OPEN_SUFFIX = "查看全文"
    private val DEFAULT_CLOSE_SUFFIX = "收起全文"
    private val ellipsis = "..."
    private var spannableString: SpannableString? = null

    init {
        val typedValue = context.obtainStyledAttributes(attrs, R.styleable.scaling_text_view)
        mOriginText = typedValue.getString(R.styleable.scaling_text_view_content_text).toString()
        mOriginTextColor = typedValue.getColor(R.styleable.scaling_text_view_content_text_color,ContextCompat.getColor(context,R.color.themeColor)).toInt()
		text = mOriginText
    }

    // 创建 ClickableSpan 对象
    val clickableSpan = object : ClickableSpan() {
        override fun onClick(widget: View) {
            // 在这里处理点击事件
            toggleText()
        }

        override fun updateDrawState(ds: TextPaint) {
            // 设置点击文字的颜色
            ds.color = Color.BLUE
            // 如果不希望点击文字有下划线,可以注释下面这行代码
            ds.isUnderlineText = true
        }
    }

    fun toggleText() {
        if (isCollapsed) {
            // 展开文本
            maxLines = Integer.MAX_VALUE
            isCollapsed = false
        } else {
            // 折叠文本
            maxLines = maxLinesCollapsed
            isCollapsed = true
        }
    }


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        if (layout.lineCount <= maxLinesCollapsed && spannableString == null) {
            //原文本等于或者小于默认折叠行数的时候不追加点击事件等
            return
        }
        if (layout != null && layout.lineCount > maxLinesCollapsed && isCollapsed) {
            val lineEndIndex = layout.getLineEnd(maxLinesCollapsed - 1)
            val newText = text.subSequence(
                0, lineEndIndex - ellipsis.length + 1 - DEFAULT_OPEN_SUFFIX.length + 1
            ).toString().trim { it <= ' ' } + ellipsis + DEFAULT_OPEN_SUFFIX
            spannableString = SpannableString(newText);
            //设置点击事件
            spannableString?.setSpan(
                clickableSpan,
                newText.lastIndexOf(DEFAULT_OPEN_SUFFIX),
                newText.lastIndexOf(DEFAULT_OPEN_SUFFIX) + DEFAULT_OPEN_SUFFIX.length,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            //设置文本颜色
            spannableString?.setSpan(
                ForegroundColorSpan(mOriginTextColor),
                newText.lastIndexOf(DEFAULT_OPEN_SUFFIX),
                newText.lastIndexOf(DEFAULT_OPEN_SUFFIX) + DEFAULT_OPEN_SUFFIX.length,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            text = spannableString
            movementMethod = LinkMovementMethod.getInstance()
            super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        }else if (layout != null && !isCollapsed) {
            val newText = mOriginText + DEFAULT_CLOSE_SUFFIX
            spannableString = SpannableString(newText);
            //设置点击事件
            spannableString?.setSpan(
                clickableSpan,
                newText.lastIndexOf(DEFAULT_CLOSE_SUFFIX),
                newText.lastIndexOf(DEFAULT_CLOSE_SUFFIX) + DEFAULT_CLOSE_SUFFIX.length,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            //设置文本颜色
            spannableString?.setSpan(
                ForegroundColorSpan(mOriginTextColor),
                newText.lastIndexOf(DEFAULT_CLOSE_SUFFIX),
                newText.lastIndexOf(DEFAULT_CLOSE_SUFFIX) + DEFAULT_CLOSE_SUFFIX.length,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            text = spannableString
            movementMethod = LinkMovementMethod.getInstance()
            super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        }

    }

}

xml里使用,这里默认是展开的,你们默认隐藏的话自己实现文章来源地址https://www.toymoban.com/news/detail-648591.html

        <com.github.demo.wight.ScalingTextView
            android:id="@+id/scalingTextView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            app:content_text="@string/scaling_str"
            app:content_text_color="@color/themeColor"" />

到了这里,关于Android实现超出固定行数折叠文字“查看全文“、“收起全文“的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 记录--多行标签超出展开折叠功能

    记录--多行标签超出展开折叠功能

     记录分享每一个日常开发项目中的实用小知识,不整那些虚头巴脑的框架理论与原理,之前分享过抽奖功能、签字功能等,有兴趣的可以看看本人以前的分享。  今天要分享的实用小知识是最近项目中遇到的标签相关的功能,我不知道叫啥,姑且称之为【多行标签展开隐藏

    2024年02月11日
    浏览(9)
  • css 实现超出两行、多行文字省略号显示

    在我们日常使用文字超出省略号显示,一般使用下面的方式实现,但是当有需求需要实现两行乃至多行时,该怎么实现呢。 单行省略: 多行省略: ps:需要注意的是,记得控制元素width。

    2024年02月11日
    浏览(18)
  • css实现,正常情况下div从左到右一次排列,宽度超出时,右侧最后一个div固定住,左侧其他div滚动
  • Element UI Dialog 对话框改成固定高度,超出部分滚动条滚动

    Element UI Dialog 对话框改成固定高度,超出部分滚动条滚动

    elememt ui 中的el-dialog对话框如果 内容过多高度会被无限拉长 。要将其设置成固定高度,此处我设置的是 页面总高度的70% ,内容过多时在对话框内出现 滚动条 。但是这样设置会造成高度不能根据内容自适应,始终是70%。可以有两种方法实现: 方法二 : 主要是运用element ui 中

    2024年02月12日
    浏览(13)
  • 文字内容超出两行时显示省略号

    设置内容超出两行显示省略号的css样式如下: 这个样式可用于uniapp的微信小程序开发。

    2024年02月13日
    浏览(11)
  • Android——使用ScrollView实现滚动效果,当内容超出屏幕范围时自动滑动显示

    Android——使用ScrollView实现滚动效果,当内容超出屏幕范围时自动滑动显示 ScrollView是Android中常用的布局容器,用于在屏幕空间有限的情况下实现内容的滑动显示。当内容超出屏幕范围时,用户可以通过滑动屏幕来查看更多内容,提供了更好的用户体验。 在Android中,使用Sc

    2024年01月16日
    浏览(6)
  • 微信小程序——CSS限制文字宽度和行数(溢出显示省略号)

    微信小程序——CSS限制文字宽度和行数(溢出显示省略号)

    知识专栏 专栏链接 微信小程序专栏 https://blog.csdn.net/xsl_hr/category_12338067.html?spm=1001.2014.3001.5482 Git版本管理 https://blog.csdn.net/XSL_HR/article/details/130986889?spm=1001.2014.3001.5501 监听页面滑动 https://blog.csdn.net/XSL_HR/article/details/130986889?spm=1001.2014.3001.5501 判断用户上滑还是下滑 https://blog

    2024年02月10日
    浏览(14)
  • vue 标题文字字数过长超出部分用...代替 动态显示

    vue 标题文字字数过长超出部分用...代替 动态显示

    效果: 浏览器最大化: 浏览器缩小:    代码: html: css:

    2024年02月14日
    浏览(5)
  • 微信小程序 text view .... 文字不换行,自动隐藏超出内容

    text-overflow: ellipsis; 文字内容溢出后加上省略点。 overflow: hidden; 控件内容溢出后直接隐藏 white-space: nowrap; 文本不会换行,文本会在在同一行上继续。 text-overflow 属性指定当文本溢出包含它的元素时,应该如何显示。可以设置溢出后,文本被剪切、显示省略号 (…) 或显示自定义

    2024年02月11日
    浏览(11)
  • git log ,查看提交次数和提交代码行数

    2.3 Git 基础 - 查看提交历史 先打开 git base , 再跳转到指定项目中,再执行以下git命令 代码提交总数统计: 贡献者/代码提交人数统计: 查看仓库提交者排名前五 查看指定人代码提交次数 查看git上个人代码量行数 统计所有成员的增删行数 Search-作者 这个命令支持的搜索参数

    2024年04月12日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包