【错误记录】Android Studio 布局文件报错 ( View with id -1: xx.MyView#onMeasure() did not set the measured dime )

2023-04-30 16:15:55 浏览数 (1)

一、报错信息

在 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)
    }
}

经过上述修改 , 报错消失 ;

0 人点赞