Android自定义Canvas水箱视图显示异常求助
Android自定义Canvas水箱视图异常排查与修复方案
可能的问题原因
- 资源文件异常:
R.drawable.hot_water_tank_container资源被误替换、不同dpi目录下的版本不一致,或资源的原始尺寸属性被修改,导致绘制基准尺寸出错。 - 测量逻辑失效:gradle插件、系统SDK版本自动更新,导致
onMeasure默认行为变化;原测量逻辑未正确处理wrap_content场景,导致View尺寸失控。 - 布局参数冲突:父布局约束、include的布局参数被意外修改,或XML中宽高设置的隐式变更,导致View实际尺寸偏离预期。
- 绘制坐标计算错误:
innerCircleCenter等参数依赖固定值或未正确基于View最终测量尺寸计算,导致水条位置偏移。
针对性解决方案
校验资源文件
- 检查
hot_water_tank_container在所有dpi目录下的资源是否一致,删除或替换错误的资源版本; - 绘制时以资源的原始尺寸为基准,通过
getDrawable().getIntrinsicWidth()/getIntrinsicHeight()获取尺寸,避免直接绑定View的测量尺寸。
- 检查
修复
onMeasure逻辑- 重写
onMeasure时,为wrap_content设置默认尺寸并保持宽高比,防止拉伸变形:@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { Drawable tankDrawable = getResources().getDrawable(R.drawable.hot_water_tank_container, getContext().getTheme()); int intrinsicWidth = tankDrawable.getIntrinsicWidth(); int intrinsicHeight = tankDrawable.getIntrinsicHeight(); int width = resolveSize(intrinsicWidth, widthMeasureSpec); int height = resolveSize(intrinsicHeight, heightMeasureSpec); // 强制保持资源的宽高比 float aspectRatio = (float) intrinsicWidth / intrinsicHeight; if ((float) width / height > aspectRatio) { width = Math.round(height * aspectRatio); } else { height = Math.round(width / aspectRatio); } setMeasuredDimension(width, height); } - XML中设置
android:layout_width="wrap_content"、android:layout_height="wrap_content",通过layout_margin或约束布局属性(如layout_constraintLeft_toLeftOf)精确定位。
- 重写
修正绘制坐标计算
- 所有绘制坐标均基于View的
getMeasuredWidth()和getMeasuredHeight()计算,避免使用固定值; - 考虑边框Drawable的内边距,计算水条的可用绘制区域:
Rect drawablePadding = new Rect(); tankDrawable.getPadding(drawablePadding); int usableWidth = getMeasuredWidth() - drawablePadding.left - drawablePadding.right; int usableHeight = getMeasuredHeight() - drawablePadding.top - drawablePadding.bottom; // 示例:计算水条的顶部位置和高度(假设水量占比为waterRatio) float waterHeight = usableHeight * waterRatio; float waterTop = getMeasuredHeight() - drawablePadding.bottom - waterHeight;
- 所有绘制坐标均基于View的
排查依赖与布局变更
- 回退gradle插件、compileSdkVersion到之前正常的版本,验证是否恢复;
- 检查父布局的代码或XML参数,确认是否有约束条件、宽高设置的意外修改。
内容的提问来源于stack exchange,提问作者VanessaF
相关产品推荐
相关产品推荐

