Android 中文两端对齐的自定义的TextView

52 阅读1分钟

Android 中文两端对齐的自定义的TextView

示例如图:

1737341998137.jpg

代码如下

package com.zw.demo20250106

import android.content.Context
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.text.SpannableString
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.TextUtils
import android.text.style.ImageSpan
import android.util.AttributeSet
import android.util.Log
import androidx.appcompat.widget.AppCompatTextView

/**
 * @Description 中文两端对齐的TextView
 * @Author zhang106209
 * @Date 2025/1/7   9:57
 *
 */

class AlignBothEndsTextView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0
) : AppCompatTextView(context, attrs, defStyle) {

    private val TAG = "AlignBothEndsTextView"

    /**
     * 字数
     */
    private var numberWord = -1


    /**
     * 实际的文本
     */
    private var realText: String = ""


    init {
        val a = context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.AlignBothEndsTextView, 0, 0
        )

        numberWord = a.getInteger(R.styleable.AlignBothEndsTextView_numberWord, -1)

        if (numberWord != -1 && numberWord != 0) {
            text = text.toString()
        }

    }

    override fun setText(text: CharSequence?, type: BufferType) {
        realText = text.toString()

        if (TextUtils.isEmpty(text.toString())) {
            super.setText(realText, type)
            return
        }
        //将str转成字符数组
        val chars: CharArray = text.toString().trim().toCharArray()

        /** 需要达到的总长度 */
        val needTextSize: Float = numberWord * this.textSize;

        /** 已有的长度 */
        var realTextSize = 0f
        for (i in chars.indices) {
            realTextSize += this.paint.measureText(chars[i].toString())
        }
        if (realTextSize >= needTextSize) {
            super.setText(realText, type)
            return
        }
        val sum = chars.size

        /** 计算字符间隔的长度 */
        val scale = (needTextSize - realTextSize) / (sum - 1).toFloat()
        Log.i(TAG, "scale==1==:$scale")
        val spannableStringBuilder = SpannableStringBuilder()
        val spaceSpan = SpannableString(" ")

        /** 使用透明的 drawable 来填充空格部分 */
        val drawable: Drawable = ColorDrawable(0x00ffffff)
        for (i in 0 until sum) {
            spannableStringBuilder.append(chars[i])
            //去除最后一个的右间距
            if (i != sum - 1) {
                //设置空白的区域
                drawable.setBounds(0, 0, scale.toInt(), 0)
                //设置图片
                spaceSpan.setSpan(ImageSpan(drawable), 0, 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
                spannableStringBuilder.append(spaceSpan)
            }
        }
        super.setText(spannableStringBuilder, type)
    }

    fun getRealText(): String {
        return realText
    }

    fun setNumberWord(numberWord: Int) {
        this.numberWord = numberWord
        setText(realText)
    }

    fun getNumberWord(): Int {
        return numberWord
    }
}