【问题标题】:Custom View layout is not drawn if onMeasure() chooses minimum size AT_MOST如果 onMeasure() 选择最小尺寸 AT_MOST,则不会绘制自定义视图布局
【发布时间】:2014-03-28 18:17:44
【问题描述】:

我的自定义视图是一个滑块,它在选择视图高度时遵循 onMeasure() 的规则,当 MeasureSpec完全 时,它设置规范大小,当它为 未指定它设置一个使用定义的大小,当它是AT_MOST它选择它们之间的最小值。

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int specHeight = Math.max(BOX_MIN_HEIGHT, MeasureSpec.getSize(heightMeasureSpec));
        int specWidth = MeasureSpec.getSize(widthMeasureSpec);

        int desiredHeight = Math.max(BOX_MIN_HEIGHT, HSVColorPickerPreference.this.boxHeight);

        int chosenHeight = 0;

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        if( heightMode == MeasureSpec.UNSPECIFIED ) {
            chosenHeight = desiredHeight;
        } else if( heightMode == MeasureSpec.AT_MOST ) {
            chosenHeight = Math.min(specHeight, desiredHeight); <<< BAD results
            //chosenHeight = specHeight; <<< GOOD results
        } else if( heightMode == MeasureSpec.EXACTLY ) {
            chosenHeight = specHeight;
        }

        setMeasuredDimension(specWidth, chosenHeight);

但这会导致视图根本不被绘制(onDraw() 未被调用)
如果我取消注释 AT_MOST 的注释行,则会绘制视图。

滑块是包含 2 个滑块和一个视图框的 LinearLayout 的一部分,每个滑块都设置了 layout_weight="1" 属性(见下图)。

下面我给你展示了好坏日志和图片(下面有两个滑块和1个视图):

好:

不好:

GOOD Log(见最后几行,致电onDraw()):

03-26 08:06:10.288: D/AlphaSlider(9223): + onSizeChanged(w:579, h:58, oldw:0, oldh:0)
03-26 08:06:10.288: D/AlphaSlider(9223): + onLayout(changed:true, left:10, top:10, right:589, bottom:68)
03-26 08:06:10.288: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:1073742185)
03-26 08:06:10.288: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=361, desiredSise=40, chosenSize=361
03-26 08:06:10.288: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:-2147483080)
03-26 08:06:10.288: W/AlphaSlider(9223): MeasureSpec AT_MOST, specSize=568, desiredSise=40, chosenSize=568
03-26 08:06:10.288: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:1073742000)
03-26 08:06:10.288: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=176, desiredSise=40, chosenSize=176
03-26 08:06:10.288: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:1073742098)
03-26 08:06:10.288: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=274, desiredSise=40, chosenSize=274
03-26 08:06:10.288: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:-2147483342)
03-26 08:06:10.288: W/AlphaSlider(9223): MeasureSpec AT_MOST, specSize=306, desiredSise=40, chosenSize=306
03-26 08:06:10.288: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:1073741913)
03-26 08:06:10.288: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=89, desiredSise=40, chosenSize=89
03-26 08:06:10.288: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:1073742098)
03-26 08:06:10.288: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=274, desiredSise=40, chosenSize=274
03-26 08:06:10.288: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:-2147483342)
03-26 08:06:10.288: W/AlphaSlider(9223): MeasureSpec AT_MOST, specSize=306, desiredSise=40, chosenSize=306
03-26 08:06:10.288: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:1073741913)
03-26 08:06:10.288: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=89, desiredSise=40, chosenSize=89
03-26 08:06:10.288: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073742185)
03-26 08:06:10.288: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=361, desiredSise=40, chosenSize=361
03-26 08:06:10.288: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:-2147483123)
03-26 08:06:10.288: W/AlphaSlider(9223): MeasureSpec AT_MOST, specSize=525, desiredSise=40, chosenSize=525
03-26 08:06:10.288: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073741986)
03-26 08:06:10.288: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=162, desiredSise=40, chosenSize=162
03-26 08:06:10.288: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073742098)
03-26 08:06:10.288: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=274, desiredSise=40, chosenSize=274
03-26 08:06:10.288: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:-2147483385)
03-26 08:06:10.288: W/AlphaSlider(9223): MeasureSpec AT_MOST, specSize=263, desiredSise=40, chosenSize=263
03-26 08:06:10.288: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073741898)
03-26 08:06:10.288: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=74, desiredSise=40, chosenSize=74
03-26 08:06:10.315: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073742169)
03-26 08:06:10.315: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=345, desiredSise=40, chosenSize=345
03-26 08:06:10.315: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:-2147483173)
03-26 08:06:10.315: W/AlphaSlider(9223): MeasureSpec AT_MOST, specSize=475, desiredSise=40, chosenSize=475
03-26 08:06:10.315: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073741969)
03-26 08:06:10.315: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=145, desiredSise=40, chosenSize=145
03-26 08:06:10.315: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073742081)
03-26 08:06:10.315: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=257, desiredSise=40, chosenSize=257
03-26 08:06:10.315: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:-2147483435)
03-26 08:06:10.315: W/AlphaSlider(9223): MeasureSpec AT_MOST, specSize=213, desiredSise=40, chosenSize=213
03-26 08:06:10.315: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073741882)
03-26 08:06:10.315: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=58, desiredSise=40, chosenSize=58
03-26 08:06:10.315: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073742081)
03-26 08:06:10.315: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=257, desiredSise=40, chosenSize=257
03-26 08:06:10.315: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:-2147483435)
03-26 08:06:10.315: W/AlphaSlider(9223): MeasureSpec AT_MOST, specSize=213, desiredSise=40, chosenSize=213
03-26 08:06:10.315: D/AlphaSlider(9223): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073741882)
03-26 08:06:10.315: W/AlphaSlider(9223): MeasureSpec EXACTLY, specSize=58, desiredSise=40, chosenSize=58
03-26 08:06:10.315: D/AlphaSlider(9223): + onLayout(changed:false, left:10, top:10, right:589, bottom:68)
03-26 08:06:10.323: D/AlphaSlider(9223): + onDraw()

错误日志(未致电onDraw()):

03-26 07:43:33.453: D/AlphaSlider(8145): + onSizeChanged(w:579, h:30, oldw:0, oldh:0)  
03-26 07:43:33.463: D/AlphaSlider(8145): + onLayout(changed:true, left:10, top:10,right:589,bottom:40)  
03-26 07:43:33.463: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:1073742185)  
03-26 07:43:33.463: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=361, desiredSise=40, chosenSize=361
03-26 07:43:33.473: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:-2147483080)
03-26 07:43:33.473: W/AlphaSlider(8145): MeasureSpec AT_MOST, specSize=568, desiredSise=40, chosenSize=40
03-26 07:43:33.473: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:1073741824)
03-26 07:43:33.473: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=30, desiredSise=40, chosenSize=30
03-26 07:43:33.473: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:1073742098)
03-26 07:43:33.473: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=274, desiredSise=40, chosenSize=274
03-26 07:43:33.473: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:-2147483342)
03-26 07:43:33.473: W/AlphaSlider(8145): MeasureSpec AT_MOST, specSize=306, desiredSise=40, chosenSize=40
03-26 07:43:33.473: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:1073741824)
03-26 07:43:33.473: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=30, desiredSise=40, chosenSize=30
03-26 07:43:33.473: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:1073742098)
03-26 07:43:33.473: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=274, desiredSise=40, chosenSize=274
03-26 07:43:33.473: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:-2147483342)
03-26 07:43:33.473: W/AlphaSlider(8145): MeasureSpec AT_MOST, specSize=306, desiredSise=40, chosenSize=40
03-26 07:43:33.473: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742360, heightMeasureSpec:1073741824)
03-26 07:43:33.473: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=30, desiredSise=40, chosenSize=30
03-26 07:43:33.473: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073742185)
03-26 07:43:33.473: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=361, desiredSise=40, chosenSize=361
03-26 07:43:33.473: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:-2147483123)
03-26 07:43:33.473: W/AlphaSlider(8145): MeasureSpec AT_MOST, specSize=525, desiredSise=40, chosenSize=40
03-26 07:43:33.473: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073741824)
03-26 07:43:33.473: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=30, desiredSise=40, chosenSize=30
03-26 07:43:33.473: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073742098)
03-26 07:43:33.473: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=274, desiredSise=40, chosenSize=274
03-26 07:43:33.473: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:-2147483385)
03-26 07:43:33.473: W/AlphaSlider(8145): MeasureSpec AT_MOST, specSize=263, desiredSise=40, chosenSize=40
03-26 07:43:33.473: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073741824)
03-26 07:43:33.473: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=30, desiredSise=40, chosenSize=30
03-26 07:43:33.503: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073742169)
03-26 07:43:33.503: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=345, desiredSise=40, chosenSize=345
03-26 07:43:33.503: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:-2147483173)
03-26 07:43:33.503: W/AlphaSlider(8145): MeasureSpec AT_MOST, specSize=475, desiredSise=40, chosenSize=40
03-26 07:43:33.503: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073741824)
03-26 07:43:33.503: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=30, desiredSise=40, chosenSize=30
03-26 07:43:33.503: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073742081)
03-26 07:43:33.503: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=257, desiredSise=40, chosenSize=257
03-26 07:43:33.503: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:-2147483435)
03-26 07:43:33.503: W/AlphaSlider(8145): MeasureSpec AT_MOST, specSize=213, desiredSise=40, chosenSize=40
03-26 07:43:33.503: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073741824)
03-26 07:43:33.503: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=30, desiredSise=40, chosenSize=30
03-26 07:43:33.503: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073742081)
03-26 07:43:33.503: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=257, desiredSise=40, chosenSize=257
03-26 07:43:33.503: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:-2147483435)
03-26 07:43:33.503: W/AlphaSlider(8145): MeasureSpec AT_MOST, specSize=213, desiredSise=40, chosenSize=40
03-26 07:43:33.503: D/AlphaSlider(8145): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073741824)
03-26 07:43:33.503: W/AlphaSlider(8145): MeasureSpec EXACTLY, specSize=30, desiredSise=40, chosenSize=30
03-26 07:43:33.503: D/AlphaSlider(8145): + onLayout(changed:false, left:10, top:10, right:589, bottom:40)

【问题讨论】:

    标签: android android-linearlayout android-custom-view ondraw


    【解决方案1】:

    既然我终于明白是怎么回事了,我把答案留在这里供以后参考:

    在测量 UI 组件时,Android 正在做它必须做的事情。
    如果用户(在这种情况下是我)不遵循简单的规则,则可能会发生 EXACTLY 0。
    如果您只在 onSizeChanged() 方法中检查 0 大小,它可以变得无害。但如果你像我一样避免混合测量模式,那就更好了。解释如下。

    我在 XML 加权视图中定义(使用 layout_weight)。这些是问题中提到的自定义视图。我的错误是还尝试为

    中的视图要求特定的高度
    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    

    罪魁祸首是线条

    int desiredHeight = Math.max(BOX_MIN_HEIGHT, HSVColorPickerPreference.this.boxHeight);
    
    . . . 
    
        chosenHeight = Math.min(specHeight, desiredHeight);
    
    . . .
    

    这与加权布局的启发式方法正面冲突。为什么?让我们以 3 个 weight=1 的小部件为例,其中一个表现不佳,如上所述。

    当 LineraLayout 第一次遍历它的孩子时,它会让他们变得疯狂并要求他们想要的任何大小。在我们的示例中,2 个小部件将要求尽可能多,自定义小部件将要求一些适度的,小于最大值。

    第二遍是杀手锏,LinearLayout 不知道其中一个加权小部件的要求低于预期,总而言之,它有一个为其定义的权重。 LinearLayout 查看请求的总测量表单通过一,发现它比它必须提供的要多。然后它计算增量溢出,并在加权的小部件之间进行另一遍分配溢出。 因此,自定义视图小部件必须削减比它请求的更多,使其大小保持为 0。

    这种情况类似于和朋友一起去喝啤酒。你点了一种啤酒,你的朋友点了啤酒,薯条,追逐者,很多。在晚上结束时,支票在每个人之间平分,你最终支付的费用比你喝的啤酒还多。我的自定义视图也是如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-03
      相关资源
      最近更新 更多