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

如何让CustomView内的TextView始终居中并适配布局宽度?

自定义ConstraintView中TextView居中及自适应尺寸问题解决

一、TextView无法居中的问题修复

原代码中使用自定义View自身ID约束TextView,容易出现ID冲突或约束失效的情况;再加上TextView旋转90度后布局测量逻辑变化,导致视觉上不居中。修复要点:

  • 移除给CustomView自身设置ID的代码,改用ConstraintSet.PARENT_ID作为约束目标,直接关联父布局
  • 确保TextView同时配置水平、垂直居中约束,旋转后仍能保持布局逻辑正确

二、让TextView根据布局宽度调整尺寸

要实现TextView随父布局宽度自适应文字大小,需正确配置自动缩放逻辑,避免硬编码固定尺寸覆盖自适应规则:

  • 移除textView.textSize=60F的硬编码设置,防止覆盖自动缩放配置
  • 保留TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration的配置,这是自适应文字大小的核心
  • 给TextView设置合理的边距,避免文字贴边影响自适应效果

修改后的完整代码

class CustomView @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null,
    defStyleAttr: Int = 0
) : ConstraintLayout(context, attributeSet, defStyleAttr) {

    private val textView: AppCompatTextView

    init {
        // 初始化背景
        background = resources.getDrawable(R.drawable.upsell_unselected_text_bg_for_discount_rectangle, context.theme)

        // 创建并配置TextView基础属性
        textView = AppCompatTextView(context).apply {
            id = R.id.vtextview
            setTextColor(resources.getColor(R.color.black, context.theme))
            text = "B"
            rotation = 90F
            isSingleLine = true
            maxLines = 1
            maxEms = 7
            ellipsize = TextUtils.TruncateAt.END
            isHorizontallyScrolling = false
            // 配置自动缩放:最小30sp,最大180sp,步长1sp
            TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(
                this, 30, 180, 1, TypedValue.COMPLEX_UNIT_SP
            )
        }

        // 添加TextView到父布局
        addView(textView)

        // 设置居中约束参数
        val layoutParams = ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.WRAP_CONTENT,
            ConstraintLayout.LayoutParams.WRAP_CONTENT
        ).apply {
            topToTop = ConstraintSet.PARENT_ID
            bottomToBottom = ConstraintSet.PARENT_ID
            startToStart = ConstraintSet.PARENT_ID
            endToEnd = ConstraintSet.PARENT_ID
            // 添边距避免文字贴边
            marginStart = 8.dpToPx(context)
            marginEnd = 8.dpToPx(context)
        }
        textView.layoutParams = layoutParams
    }

    // DP转PX工具方法
    private fun Int.dpToPx(context: Context): Int {
        return TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            this.toFloat(),
            context.resources.displayMetrics
        ).toInt()
    }

    // 对外暴露的设置方法
    fun setTextSize(textSize: Float) {
        // 若需手动设置,建议先关闭自动缩放:
        // TextViewCompat.setAutoSizeTextTypeWithDefaults(textView, TextViewCompat.AUTO_SIZE_TEXT_TYPE_NONE)
        textView.textSize = textSize
    }

    fun setTextColor(color: Int) {
        textView.setTextColor(color)
    }

    fun setText(str: String) {
        textView.text = str
    }
}

关键修改说明

  1. 约束目标改为PARENT_ID:彻底避免自定义View自身ID带来的潜在问题,确保无论父布局尺寸如何,TextView都能稳定居中
  2. 移除固定textSize:让自动缩放逻辑正常工作,TextView会根据可用宽度自动调整文字大小
  3. 补充构造函数参数:符合Android自定义View的规范,支持多场景初始化
  4. 添加边距:优化视觉效果,避免文字贴边导致的自适应异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 05:45:30