Android如何实现自定义View动态占满整个屏幕(match_parent效果)
自定义View实现match_parent占满可用空间的正确方案
原写法失效原因
你之前的代码不生效和布局初始化时机无关,核心是用错了MATCH_PARENT常量:
ViewGroup.LayoutParams.MATCH_PARENT是给布局参数用的标记常量,实际值为-1,仅用于告诉父布局当前View的测量规则,不能直接当作实际尺寸值用于绘制。- 你初始化
RectF时传入-1f作为右、下边界,实际绘制区域是坐标(-1,-1)到(0,0),完全落在View可见绘制区域外,自然看不到任何内容。
实现步骤
1. 先给View设置正确的布局参数
不管是XML布局声明还是代码动态添加,都要先把FloorView自身的布局宽高设为match_parent:
- XML写法示例:
<com.your.packagename.FloorView android:layout_width="match_parent" android:layout_height="match_parent"/>
- 代码动态添加写法示例:
val floorView = FloorView(context, null) floorView.layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) parentLayout.addView(floorView)
2. 修正自定义View内部的绘制逻辑
View的实际宽高需要等测量、布局流程完成后才能确定,不要在类初始化时就写死绘制区域的坐标,在尺寸变化的回调里动态更新绘制边界即可,修正后的完整代码如下:
class FloorView(context: Context, attrs: AttributeSet) : View(context, attrs) { private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { style = Paint.Style.FILL_AND_STROKE color = Color.BLACK } // 先声明空的Rect对象,不要在初始化时传入固定值 private val rectangle = RectF() override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { super.onSizeChanged(w, h, oldw, oldh) // View尺寸确定/发生变化时,用实际宽高更新矩形边界:左上(0,0) 右下(w,h) rectangle.set(0f, 0f, w.toFloat(), h.toFloat()) } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) canvas.drawRect(rectangle, paint) } }
补充说明
onSizeChanged会在View第一次完成测量、以及后续尺寸发生变化(比如横竖屏切换、父布局尺寸调整)时触发,在这里更新绘制区域不需要硬编码任何尺寸值,会自动适配当前View分配到的全部可用空间,完全达到match_parent的效果。- 不建议在
onDraw方法里每次执行都创建Rect对象或者计算边界,会增加不必要的性能开销,在onSizeChanged里提前更新复用Rect是更优的写法。
内容的提问来源于stack exchange,提问作者meniman98
相关产品推荐
相关产品推荐

