一、报错信息
在 ConstraintLayout 约束布局中 , 引入了自定义 View 后 , 整个 Design 图形化操作界面没了 , 报错信息如下 :
代码语言:javascript复制java.lang.IllegalStateException: View with id -1: com.example.MyView#onMeasure() did not set the measured dimension by calling setMeasuredDimension()
at android.view.View.measure_Original(View.java:25786)
at android.view.View_Delegate.measure(View_Delegate.java:80)
at android.view.View.measure(View.java:25737)
at androidx.constraintlayout.widget.ConstraintLayout$Measurer.measure(ConstraintLayout.java:811)
at androidx.constraintlayout.core.widgets.analyzer.BasicMeasure.measure(BasicMeasure.java:466)
at androidx.constraintlayout.core.widgets.analyzer.BasicMeasure.solverMeasure(BasicMeasure.java:372)
at androidx.constraintlayout.core.widgets.ConstraintWidgetContainer.measure(ConstraintWidgetContainer.java:120)
at androidx.constraintlayout.widget.ConstraintLayout.resolveSystem(ConstraintLayout.java:1594)
at androidx.constraintlayout.widget.ConstraintLayout.onMeasure_Original(ConstraintLayout.java:1708)
at androidx.constraintlayout.widget.ConstraintLayout.onMeasure(ConstraintLayout.java)
at android.view.View.measure_Original(View.java:25773)
at android.view.View_Delegate.measure(View_Delegate.java:80)
at android.view.View.measure(View.java:25737)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6980)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure_Original(View.java:25773)
at android.view.View_Delegate.measure(View_Delegate.java:80)
at android.view.View.measure(View.java:25737)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:735)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:481)
at android.view.View.measure_Original(View.java:25773)
at android.view.View_Delegate.measure(View_Delegate.java:80)
at android.view.View.measure(View.java:25737)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6980)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure_Original(View.java:25773)
at android.view.View_Delegate.measure(View_Delegate.java:80)
at android.view.View.measure(View.java:25737)
at com.android.layoutlib.bridge.impl.RenderSessionImpl.measureView(RenderSessionImpl.java:657)
at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:375)
at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:436)
at com.android.tools.idea.layoutlib.LayoutLibrary.createSession(LayoutLibrary.java:121)
at com.android.tools.idea.rendering.RenderTask.createRenderSession(RenderTask.java:717)
at com.android.tools.idea.rendering.RenderTask.lambda$inflate$9(RenderTask.java:873)
at com.android.tools.idea.rendering.RenderExecutor$runAsyncActionWithTimeout$3.run(RenderExecutor.kt:192)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
二、解决方案
出现上述报错问题 , 是由于在 自定义 View 或 ViewGroup 的 onMeasure() 方法 中 没有调用 setMeasuredDimension() 方法导致的 ;
实现 onMeasure() 方法时,需要 调用 setMeasuredDimension() 来设置 View 或 ViewGroup 的测量宽度和高度。
如果您没有调用 setMeasuredDimension(),则会发报 “View#onMeasure() did not set the measured dimension by calling setMeasuredDimension()” 警告,并且该视图可能无法正常显示。
以下是一个示例,在这个示例中,自定义 View 的 onMeasure() 方法调用了 setMeasuredDimension() 来设置 View 的测量宽度和高度。
代码语言:javascript复制class CustomView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
// Measure the view's width
val width = MeasureSpec.getSize(widthMeasureSpec)
// Calculate the view's height based on the width and aspect ratio
val aspectRatio = 0.75f
val height = (width * aspectRatio).toInt()
// Set the measured dimensions
setMeasuredDimension(width, height)
}
}
在上述示例中 :
- 首先 , 使用 MeasureSpec.getSize() 方法来获取视图的宽度。
- 然后 , 使用一个固定的宽高比(0.75f)计算出视图的高度。
- 最后 , 调用 setMeasuredDimension() 方法来设置视图的测量宽度和高度。
实现 onMeasure() 方法时,必须在最后 调用 setMeasuredDimension() 来设置视图的测量宽度和高度。
否则,会报 “View#onMeasure() did not set the measured dimension by calling setMeasuredDimension()” 警告,并且视图可能无法正常显示。
在本案例中 , 源码如下 :
代码语言:javascript复制import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout
class MyView(context: Context, attrs: AttributeSet?) : ConstraintLayout(context, attrs) {
init {
val inflater = LayoutInflater.from(context)
inflater.inflate(R.layout.item_left_path, this, true)
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
// Your layout code here
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
// Your measure code here
}
}
如果没有使用到 布局 / 测量逻辑 , 直接将这两个函数删除 ;
代码语言:javascript复制import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout
class MyView(context: Context, attrs: AttributeSet?) : ConstraintLayout(context, attrs) {
init {
val inflater = LayoutInflater.from(context)
inflater.inflate(R.layout.item_left_path, this, true)
}
}
经过上述修改 , 报错消失 ;