You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android TextView:将文本拆分为等长两行并自适应宽度的实现问题

解决TextView平衡换行后宽度无法收缩的问题

我之前做类似需求的时候也踩过这个坑!android:breakStrategy="balanced"确实能帮我们把文本拆分成尽量等长的两行,但wrap_content的测量逻辑有点“死板”——它会先按照文本不换行的宽度计算默认尺寸,之后才会应用换行策略,所以最终TextView的宽度还是会保留原单行文本的宽度,没法自动收缩到换行后单行的实际宽度。

要解决这个问题,我们需要自定义TextView,重写它的测量逻辑,让它在平衡换行后重新计算实际需要的宽度。

自定义BalancedWrapTextView

这里提供一个Kotlin版本的自定义TextView,你可以直接复制使用(Java版本逻辑完全一致,转译即可):

class BalancedWrapTextView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = android.R.attr.textViewStyle
) : AppCompatTextView(context, attrs, defStyleAttr) {

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        // 先让系统完成初始测量,应用换行策略
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        
        // 仅当宽度设置为wrap_content(AT_MOST模式)时才处理
        if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST) {
            val layout = layout ?: return
            
            // 遍历所有行,找到最宽的那一行的宽度(平衡换行后两行宽度几乎一致)
            var maxLineWidth = 0f
            for (i in 0 until layout.lineCount) {
                val lineWidth = layout.getLineWidth(i)
                if (lineWidth > maxLineWidth) {
                    maxLineWidth = lineWidth
                }
            }
            
            // 加上左右padding,转换为实际需要的宽度值
            val desiredWidth = (maxLineWidth + paddingLeft + paddingRight).toInt()
            // 重新生成测量规格,强制TextView使用计算出的宽度
            val newWidthSpec = MeasureSpec.makeMeasureSpec(desiredWidth, MeasureSpec.EXACTLY)
            // 再次调用测量,应用新的宽度
            super.onMeasure(newWidthSpec, heightMeasureSpec)
        }
    }
}

布局中使用

在你的XML布局里替换原来的TextView,同时记得设置maxLines="2"(确保文本只会拆成两行)和breakStrategy="balanced":

<com.your.package.name.BalancedWrapTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:breakStrategy="balanced"
    android:maxLines="2"
    android:text="这里是你需要拆分的长文本内容" />

注意事项

  • 必须设置android:maxLines="2",否则balanced策略可能会根据文本长度拆分成更多行,影响最终宽度计算
  • 如果文本本身很短不需要换行,这个自定义View会自动 fallback 到正常的wrap_content行为
  • 如果你使用的是Java项目,只需要把上述Kotlin代码转译为Java即可,核心逻辑(重新测量宽度)保持不变

内容的提问来源于stack exchange,提问作者JJAlexander

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 13:47:44