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
相关产品推荐
相关产品推荐

