Android自定义View为何占据整个屏幕空间?
自定义View实现wrap_content效果解决方案
自定义View默认不会自动支持wrap_content,因为系统默认的onMeasure逻辑会让View占满父容器的可用空间。要让你的MyView只包裹绘制的黑色矩形区域,需要重写onMeasure方法来指定View的期望尺寸。
修改后的MyView代码
public class MyView extends View { // 对应绘制矩形的右下角坐标,确保View能容纳整个矩形 private static final int DESIRED_WIDTH = 220; private static final int DESIRED_HEIGHT = 220; public MyView(Context context) { super(context); setBackgroundColor(Color.RED); } public MyView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { canvas.drawRect(20,20,220,220,new Paint()); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 处理宽度测量 int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int finalWidth; if (widthMode == MeasureSpec.EXACTLY) { // 对应match_parent或固定宽度,直接使用父容器给出的尺寸 finalWidth = widthSize; } else { // 对应wrap_content,使用自定义的期望宽度,同时不超过父容器可用空间 finalWidth = Math.min(DESIRED_WIDTH, widthSize); } // 处理高度测量,逻辑和宽度一致 int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int finalHeight; if (heightMode == MeasureSpec.EXACTLY) { finalHeight = heightSize; } else { finalHeight = Math.min(DESIRED_HEIGHT, heightSize); } // 设置最终测量的宽高 setMeasuredDimension(finalWidth, finalHeight); } }
代码说明
- 定义
DESIRED_WIDTH和DESIRED_HEIGHT:对应你绘制的黑色矩形右下角坐标(220,220),保证View的大小刚好能容纳整个矩形区域。 - 重写
onMeasure:- 区分父容器的测量模式:
EXACTLY对应固定尺寸或match_parent,直接使用父容器给出的尺寸;AT_MOST/UNSPECIFIED对应wrap_content,使用自定义的期望尺寸,同时限制不超过父容器的可用空间。 - 调用
setMeasuredDimension将计算好的宽高传给系统,系统就会按照这个尺寸布局View。
- 区分父容器的测量模式:
修改完成后,你添加到LinearLayout中的两个MyView就会只占用黑色矩形对应的空间,实现wrap_content的效果。
内容的提问来源于stack exchange,提问作者Benderson Phanor
相关产品推荐
相关产品推荐

