Android onMeasure and draw()

Android onMeasure and draw(),android,android-layout,Android,Android Layout,我有一些非常奇怪的问题 第一个问题如下: 我阅读了如何覆盖onMeasure()。我做到了。我希望在onMeasure中设置宽度/高度时,它们在onDraw中会完全相同,但显然这不是真的。 除此之外,我还注意到测量的宽度将与绘图阶段的宽度相同,但再次说明这不是真的 可以多次调用onMeasure。每次调用时,我都会调用setMeasuredDimension,并计算宽度和高度。例如,第一次我的视图应该是480 x 245,第二次调用时,我再次计算它,当然是基于父视图,它应该是90 x 245 让

我有一些非常奇怪的问题

第一个问题如下: 我阅读了如何覆盖onMeasure()。我做到了。我希望在onMeasure中设置宽度/高度时,它们在onDraw中会完全相同,但显然这不是真的。 除此之外,我还注意到测量的宽度将与绘图阶段的宽度相同,但再次说明这不是真的

可以多次调用onMeasure。每次调用时,我都会调用setMeasuredDimension,并计算宽度和高度。例如,第一次我的视图应该是480 x 245,第二次调用时,我再次计算它,当然是基于父视图,它应该是90 x 245

让我大吃一惊的是,除了第一次呼叫,安卓几乎什么都不理。所以在这种情况下,我的最终视图大小是480 x 245

第二期如下: 我的视图高度为匹配父视图,父视图高度为0。那么,在我不知道的情况下,我应该如何在测量上设置正确的高度呢


您知道如何让android不忽略我的setMeasureDimensions调用以及如何设置match\u parent吗?

分配给视图的空间不仅仅取决于您测量的大小,下面是该过程的快照:

  • View.onMeasure
    在测量父对象的过程中被调用。你得到了你的
    MeasureSpec
    ,基本上就是你最多可以占用多少空间(非常概括)

  • 根据这些规格,您可以确定自己的大小,从逻辑上测量您自己的孩子并调用
    setMeasuredDimension

  • 一段时间后,你的父母会根据你的测量结果为你指定具体的尺寸(但这也意味着它可能会有所不同)。然后,因为这些将是你的维度,这就是你必须使用的维度。此时调用的回调是
    onLayout
    ,您应该根据受影响的维度在流程中布局您的子级

  • 所有这些之后,将绘制您的
    视图
    ,即
    视图。调用dispatchDraw
    ,并生成到
    onDraw
    的简单视图。如果您是
    视图组
    ,则绘制自己也意味着绘制您的孩子

  • 绘制时,系统将传递一个尺寸为屏幕尺寸的
    画布
    ,并使用平移和剪裁将画布沿视图传递,以便它们自己绘制。这样可以避免在提取期间进行分配。因此,如果您想知道哪些空间是专用于您的,您不应该使用
    Canvas.getWidth
    Canvas.getHeight
    作为屏幕的尺寸,而应该检索剪裁的尺寸(
    Canvas.getClipBounds()

  • 最后,正确检索剪辑边界时,它们通常应与宽度和高度相同(
    View.getWidth
    View.getHeight
    ),但它们可能不同,例如,如果画布被缩放

因此,总结一下:

  • onMeasure
    目的是确定子对象的大小,以便
    ViewGroup
    可以计算出子对象的大小

  • onLayout
    目的是影响每个视图的宽度和高度,并传播到子视图

  • onDraw
    目的是渲染视图


  • 谢谢你的回答,但我的情况不同。我测量的是视图而不是视图组。另外,我试图使我的视图小于可用空间,而Android并没有听我说。它只接受来自第一个setMeasuredDimensions调用的“宽度”,但高度是正确的。所以从第一次调用开始接受宽度,从最后一次调用开始接受高度…:(你不能阻止你的父母给你比你希望的更多的空间。但是,你可以把自己画在专用于你的空间的中心;)