我的自定义视图是一个滑块,在选择视图高度时遵循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"
(参见下图)。
下面我将向您展示好的和坏的日志和图像(下面有两个滑块和一个视图):
好的:
坏:
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()
BAD Log(不调用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)
答案 0 :(得分:0)
因为我终于明白了发生了什么,所以我留下答案以供将来参考:
Android在测量UI组件时正在做它必须做的事情
如果用户(在这种情况下我)不遵循简单规则,则可能会发生完全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);
. . .
这与加权布局的启发式发生冲突。为什么?让我们举例说明权重= 1的3个小部件,其中一个表现不好,如上所述。
当LineraLayout首次通过其子项时,它会让它们变得疯狂并要求任何他们想要的大小。在我们的示例中,2个小部件将尽可能地要求,自定义小部件将要求适度的,小于最大值。
第二遍是杀手,LinearLayout不知道其中一个加权小部件要求的数量少于预期,总而言之,它有一个为它定义的权重。 LinearLayout查看传递的总请求度量表单,并且看到它比它必须给出的更多。然后它计算delta溢出并进行另一次传递,在加权小部件之间分配溢出。 因此,自定义视图小部件必须减少超过其请求的数量,使其保持0大小。
情况类似于和朋友一起喝啤酒。你点一杯啤酒,你的朋友点啤酒,薯条,追逐者,这个地段。在晚上结束时,支票在每个人之间平均分配,最终支付的费用超过了你的啤酒。我的自定义视图也是如此。