小需求:默认展示4行,超过4行出现“查看全部”,点击则加载浮层显示完整内容;

实现是参考下面网址代码,但是有一些改动(主要涉及纯引英文的文本下面网址的代码可能有些问题)

https://www.jianshu.com/p/f4f99eb932d4

 

最终显示代码如下:

import android.content.Contextimport android.graphics.Colorimport android.support.v7.widget.AppCompatTextViewimport android.text.Spannableimport android.text.SpannableStringBuilderimport android.text.TextPaintimport android.text.TextUtilsimport android.text.method.LinkMovementMethodimport android.text.style.ClickableSpanimport android.util.AttributeSetimport android.view.Viewimport android.widget.Toast/** * @date: 2020.02.25 */class FoldTextView : AppCompatTextView {    private var isSupportFold = false    private var clickCallback: TextClickCallback? = null    private var isNeedEllipsis = true    constructor(context: Context) : this(context, null) {    }    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) {}    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {        val ta = context.obtainStyledAttributes(attrs, R.styleable.PayFoldTextView)        isSupportFold = ta.getBoolean(R.styleable.FoldTextView_supportFold, false)    }    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec)        if (isSupportFold) {            //获取当前的行数            val lineCount = lineCount            val layout = layout            val maxLines = maxLines            if (maxLines == 0 || lineCount < maxLines || TextUtils.isEmpty(text)) {                return            }            val totalChars = layout.getLineEnd(maxLines - 1)            val lastLineStartIndex = layout.getLineStart(maxLines - 1)            if (totalChars >= text.length) {                return            }            val mustShowText = text.subSequence(0, lastLineStartIndex)            val tailWidth = paint.measureText(TAIL_TEXT)            var lastLineText: CharSequence            if (LINE_BREAKER == text[totalChars - 1].toString()) {                lastLineText = text.subSequence(lastLineStartIndex, totalChars - 1)            } else {                lastLineText = text.subSequence(lastLineStartIndex, totalChars)            }            val maxWidth = measuredWidth.toFloat()            val ellipsizeLastLineText = TextUtils.ellipsize(                    lastLineText, paint, maxWidth - tailWidth,                    TextUtils.TruncateAt.END            )            if (ellipsizeLastLineText.length > 2 && ellipsizeLastLineText != lastLineText) {                lastLineText = ellipsizeLastLineText.subSequence(0, ellipsizeLastLineText.length - 1)                isNeedEllipsis = true            } else {                isNeedEllipsis = false            }            val spannableStringBuilder = SpannableStringBuilder(mustShowText)            if (!mustShowText.endsWith("\n")) {                spannableStringBuilder.append(LINE_BREAKER)            }            spannableStringBuilder.append(lastLineText)            if (isNeedEllipsis) {                spannableStringBuilder.append("...")                spannableStringBuilder.append(TAIL_SEPARATOR)            } else {                spannableStringBuilder.append(TAIL_SEPARATOR_O)            }            spannableStringBuilder.append(buildClickText())            //重新设置文本            movementMethod = LinkMovementMethod.getInstance()            highlightColor = Color.TRANSPARENT //设置点击后的颜色为透明            super.setText(spannableStringBuilder)        }    }    companion object {        val LINE_BREAKER = "\n"        val TAIL_TEXT = "...查看全部"        val TAIL_SEPARATOR = "    "        val TAIL_SEPARATOR_O = " "        val TAIL_TEXT_WITHOUT_ELLIPSIS = "查看全部"    }    fun setClickCallback(clickCallback: TextClickCallback?) {        this.clickCallback = clickCallback    }    private fun buildClickText(): SpannableStringBuilder {        val spannableString =                SpannableStringBuilder(TAIL_TEXT_WITHOUT_ELLIPSIS)        val clickableSpan = object : ClickableSpan() {            override fun onClick(widget: View) {                clickCallback?.respondClick()            }            override fun updateDrawState(ds: TextPaint) {                super.updateDrawState(ds)                ds.color = resources.getColor(R.color.pay_color_0086f6)                ds.isUnderlineText = false            }        }        spannableString.setSpan(clickableSpan, 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)        return spannableString    }    fun setSupportFold(isSupport: Boolean = false) {        isSupportFold = isSupport        maxLines = Integer.MAX_VALUE    }}

 

    

相关注释:

supportFold:是否需要支持文本折叠。

buildClickText()方法主要是给查看全部添加点击事件以及相关样式。

下面代码是:指定Paint属性的宽度下的文本是否与原始文本相同,不相同则需要显示省略号及查看全部。

 

 if (ellipsizeLastLineText.length > 2 && ellipsizeLastLineText != lastLineText) {                lastLineText = ellipsizeLastLineText.subSequence(0, ellipsizeLastLineText.length - 1)                isNeedEllipsis = true            } else {                isNeedEllipsis = false            }

 

ellipsize方法需要的相关参数:

text:原始的文本内容 paint:canvas用到的画笔 avail:画布能提供的宽度 where:枚举类型,就是 省略号显示的位置

/** * Returns the original text if it fits in the specified width * given the properties of the specified Paint, * or, if it does not fit, a truncated * copy with ellipsis character added at the specified edge or center. */public static CharSequence ellipsize(CharSequence text,                                     TextPaint p,                                     float avail, TruncateAt where) {    return ellipsize(text, p, avail, where, false, null);}

下面的代码加上"\n"是因为在英文条件下,最后一行的文字可能会显示到倒数第二行,所以强制加上换行符。

  val spannableStringBuilder = SpannableStringBuilder(mustShowText)            if (!mustShowText.endsWith("\n")) {                spannableStringBuilder.append(LINE_BREAKER)            }

 

 

更多相关文章

  1. Android高德地图开发(2)——地图显示+自定义控件
  2. Android(安卓)在App中启动另一个App
  3. Android下EditText的hint的一种显示效果------FloatLabelLayout
  4. Android使用ListView构造复杂界面,响应点击事件,通过Intent跳转act
  5. Android(安卓)-- SpannableString 实现富文本效果用法全解析
  6. 修改Android默认启动项launcher
  7. Android课程表显示
  8. android sdk 编译--如何将源代码加入android.jar,以及make原理
  9. Android(安卓)Studio使用技巧系列教程(三)

随机推荐

  1. ViewGroup常用布局操作
  2. Android 输入框限制字符输入数
  3. android 在surface上显示YUV 笔记
  4. 转:Android 开发技巧杂集
  5. Android应用开发中如何进行单元测试
  6. android中wifi原理及流程分析
  7. Android Network Resources
  8. JS与Android交互之html页面跳转到Android
  9. android界面布局
  10. 在Android中Preferences数据存储的使用