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

Android自定义View从Styleable获取SP值异常问题求助

解决自定义View从Styleable获取SP值显示异常的问题

嘿,我懂你碰到的这个问题了!当你用getDimensionPixelSize()或者getDimension()获取XML里设置的SP尺寸后,设置给TextView时显示得异常大,核心原因出在单位不匹配上:

问题根源

TextView.setTextSize(float size)这个方法默认把传入的数值当成SP单位来处理,但你通过getDimensionPixelSize()拿到的是已经经过密度转换的**像素(PX)**值。举个例子:假设你在XML里设了15sp,在xxhdpi设备上会被转换成45px,你把45传给setTextSize()后,TextView会把它当成45sp再转一次像素,结果变成135px,自然就显得特别大了。

解决方案

这里有两种靠谱的解决方式,你可以根据需求选择:

方案一:直接用像素单位设置(简单直接)

既然你已经拿到了适配好的像素值,那就明确告诉TextView用像素单位来解析它:

private fun setAttrs(context: Context?, attrs: AttributeSet?) {
    val typedArray = context?.obtainStyledAttributes(attrs, R.styleable.TagView, 0, 0)
    typedArray?.run {
        val tagText = getString(R.styleable.TagView_tagText)
        val tagSize = getDimensionPixelSize(R.styleable.TagView_tagTextSize, 0)
        val tagTextColor = getColor(R.styleable.TagView_tagTextColor, Color.WHITE)
        
        tagText?.let { nameTextView?.text = it }
        if (tagSize != 0) {
            // 明确指定像素单位,避免TextView默认按SP解析
            nameTextView?.setTextSize(TypedValue.COMPLEX_UNIT_PX, tagSize.toFloat())
        }
        nameTextView?.setTextColor(tagTextColor)
        recycle()
    }
}

方案二:保留SP的字体缩放特性(更符合SP设计初衷)

如果你希望文字大小能跟随系统的字体缩放设置变化,那可以直接获取原始的维度单位和值,传递给TextView:

private fun setAttrs(context: Context?, attrs: AttributeSet?) {
    val typedArray = context?.obtainStyledAttributes(attrs, R.styleable.TagView, 0, 0)
    typedArray?.run {
        val tagText = getString(R.styleable.TagView_tagText)
        val tagTextColor = getColor(R.styleable.TagView_tagTextColor, Color.WHITE)
        
        tagText?.let { nameTextView?.text = it }
        
        // 获取原始的TypedValue,保留单位信息
        val tagSizeValue = TypedValue()
        if (getValue(R.styleable.TagView_tagTextSize, tagSizeValue)) {
            nameTextView?.setTextSize(tagSizeValue.type, tagSizeValue.floatValue)
        }
        
        nameTextView?.setTextColor(tagTextColor)
        recycle()
    }
}

额外说明

你的styleable.xml里tagTextSize的format="dimension"是完全正确的,因为SP本身就是Android支持的维度类型之一,不需要修改这个配置。

内容的提问来源于stack exchange,提问作者felipe.rce

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:04:47