How to use custom ellipsis in Android TextView

前端 未结 5 1834
陌清茗
陌清茗 2020-12-31 09:55

I have a TextView with maxlines=3 and I would like to use my own ellipsis, instead of

\"Lore ipsum ...\"

I need

\"Lore ips         


        
5条回答
  •  梦谈多话
    2020-12-31 10:36

    Here's a nice way to do it with a Kotlin extension. Note that we need to wait for the view to layout before we can measure and append the suffix.

    In TextViewExtensions.kt

    fun TextView.setEllipsizedSuffix(maxLines: Int, suffix: String) {
        addOnLayoutChangeListener(object: View.OnLayoutChangeListener {
            override fun onLayoutChange(v: View?, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom:     Int) {
    
                val allText = text.toString()
                var newText = allText
                val tvWidth = width
                val textSize = textSize
    
                if(!TextUtil.textHasEllipsized(newText, tvWidth, textSize, maxLines)) return
    
                while (TextUtil.textHasEllipsized(newText, tvWidth, textSize, maxLines)) {
                    newText = newText.substring(0, newText.length - 1).trim()
                }
    
                //now replace the last few chars with the suffix if we can
                val endIndex = newText.length - suffix.length - 1 //minus 1 just to make sure we have enough room
                if(endIndex > 0) {
                    newText = "${newText.substring(0, endIndex).trim()}$suffix"
                }
    
                text = newText
    
                removeOnLayoutChangeListener(this)
            }
        })
    }
    

    In TextUtil.kt

    fun textHasEllipsized(text: String, tvWidth: Int, textSize: Float, maxLines: Int): Boolean {
        val paint = Paint()
        paint.textSize = textSize
        val size = paint.measureText(text).toInt()
    
        return size > tvWidth * maxLines
    }
    

    Then actually using it like this myTextView.setEllipsizedSuffix(2, "...See more")


    Note: if your text comes from a server and may have new line characters, then you can use this method to determine if the text has ellipsized.

    fun textHasEllipsized(text: String, tvWidth: Int, textSize: Float, maxLines: Int): Boolean {
        val paint = Paint()
        paint.textSize = textSize
        val size = paint.measureText(text).toInt()
        val newLineChars = StringUtils.countMatches(text, "\n")
    
        return size > tvWidth * maxLines || newLineChars >= maxLines
    }
    

    StringUtils is from implementation 'org.apache.commons:commons-lang3:3.4'

提交回复
热议问题