正确处理wrap_content和padding是一个高质量自定义View的基本要求。忽略它们会导致View在要求自适应内容时无法正确测量,或者内容与边界重叠,严重影响可用性和复用性。我将从测量和绘制两个阶段,详细说明如何正确处理。”
第一部分:正确处理 wrap_content
核心问题:当布局参数为wrap_content时,父View传入的MeasureSpec模式是AT_MOST,我们需要返回一个内容期望的尺寸,且不能超过父View给出的限制。
常见的错误做法
kotlin
// ❌ 错误示例:完全忽略了 wrap_content
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
// 直接设置一个固定值,或者直接使用父View给的最大值
setMeasuredDimension(200, 200) // 固定大小,wrap_content 失效
// 或
setMeasuredDimension(
MeasureSpec.getSize(widthMeasureSpec), // 直接填满,行为像 match_parent
MeasureSpec.getSize(heightMeasureSpec)
)
}
正确的处理方案
1. 计算内容的期望尺寸
首先,你需要计算出你的View在没有任何约束时,显示其内容所需要的理想尺寸。
kotlin
private fun calculateDesiredSize(): Pair<Int, Int> {
// 这里根据你的View内容来计算
// 例如:如果是画一段文字
val text = "Hello World"
val textPaint = Paint().apply {
textSize = this@CustomView.textSize
}
val textWidth = textPaint.measureText(text).roundToInt()
val textHeight = textPaint.fontMetrics.let { it.bottom - it.top }.roundToInt()
// 如果是画一个图标,可能就是图标的宽高
// val desiredWidth = icon.intrinsicWidth
// val desiredHeight = icon.intrinsicHeig
自定义View处理wrap_content和padding

最低0.47元/天 解锁文章
1514

被折叠的 条评论
为什么被折叠?



