在调试自定义视图时,我重写了
我只处理视图的高度,始终不改变宽度规格。
在某个时刻,我会收到一个(高度)MeasureSpec
这没有意义,而且违反了Android文档:
我怀疑这个调用是因为在布局XML中,视图具有
这是代码:
这是日志,注意最后几次调用
onMeasure()
方法,发现有多次调用该方法。我只处理视图的高度,始终不改变宽度规格。
在某个时刻,我会收到一个(高度)MeasureSpec
getMode()
== EXACTLY
和getSize()
== 0的调用。这没有意义,而且违反了Android文档:
MeasureSpecs are used to push requirements down the tree from parent to child.
A MeasureSpec can be in one of three modes:
UNSPECIFIED: This is used by a parent to determine the desired dimension of a child
view. For example, a LinearLayout may call measure() on its child with the height set
to UNSPECIFIED and a width of EXACTLY 240 to find out how tall the child view wants
to be given a width of 240 pixels.
EXACTLY: This is used by the parent to impose an exact size on the child. The child
must use this size, and guarantee that all of its descendants will fit within this
size.
AT_MOST: This is used by the parent to impose a maximum size on the child. The child
must guarantee that it and all of its descendants will fit within this size.
如果我按照预期的做法(孩子必须使用这个尺寸),setMeasureDimension(specWidth, sepcHeight)
,我会收到一个异常,告诉我视图的宽度和高度必须>0。我怀疑这个调用是因为在布局XML中,视图具有
layout_weight="1"
,并且根据文档建议:但是,当MeasureSpec模式为EXACTLY时,大小应该>0。或者至少应该在文档中遵循一些规则来解决这些情况。要创建一个线性布局,在屏幕上每个子元素使用相同的空间,请将每个视图的android:layout_height设置为"0dp"
这是代码:
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int specHeight = 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);
} else if( heightMode == MeasureSpec.EXACTLY ) {
chosenHeight = specHeight;
}
setMeasuredDimension(specWidth, chosenHeight);
这是日志,注意最后几次调用
onMeasure()
:03-29 08:17:13.388: D/ValueSlider(1384): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:-2147483435)
03-29 08:17:13.388: W/ValueSlider(1384): MeasureSpec AT_MOST, specSize=213, desiredSize=40, chosenSize=40
03-29 08:17:13.388: D/AlphaSlider(1384): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:-2147483435)
03-29 08:17:13.388: W/AlphaSlider(1384): MeasureSpec AT_MOST, specSize=213, desiredSize=40, chosenSize=40
03-29 08:17:13.388: D/ValueSlider(1384): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073741824)
03-29 08:17:13.388: W/ValueSlider(1384): MeasureSpec EXACTLY, specSize=0, desiredSize=40, chosenSize=0
03-29 08:17:13.388: D/AlphaSlider(1384): + onMeasure(widthMeasureSpec:1073742403, heightMeasureSpec:1073741824)
03-29 08:17:13.388: W/AlphaSlider(1384): MeasureSpec EXACTLY, specSize=0, desiredSize=40, chosenSize=0
03-29 08:17:13.508: D/ValueSlider(1384): + onSizeChanged(w:579, h:0, oldw:0, oldh:0)
03-29 08:17:13.508: D/AndroidRuntime(1384): Shutting down VM
03-29 08:17:13.508: W/dalvikvm(1384): threadid=1: thread exiting with uncaught exception (group=0xb2fe0180)
03-29 08:17:13.518: E/AndroidRuntime(1384): FATAL EXCEPTION: main
03-29 08:17:13.518: E/AndroidRuntime(1384): java.lang.IllegalArgumentException: width and height must be > 0
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.graphics.Bitmap.createBitmap(Bitmap.java:603)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.graphics.Bitmap.createBitmap(Bitmap.java:585)
03-29 08:17:13.518: E/AndroidRuntime(1384): at com.UturpatShuPepper.lib.HSVColorPickerPreference$Slider.onSizeChanged(HSVColorPickerPreference.java:962)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.View.setFrame(View.java:11361)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.View.layout(View.java:11272)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.View.layout(View.java:11278)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.ViewGroup.layout(ViewGroup.java:4224)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.View.layout(View.java:11278)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.ViewGroup.layout(ViewGroup.java:4224)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.widget.RelativeLayout.onLayout(RelativeLayout.java:925)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.View.layout(View.java:11278)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.ViewGroup.layout(ViewGroup.java:4224)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.View.layout(View.java:11278)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.ViewGroup.layout(ViewGroup.java:4224)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.View.layout(View.java:11278)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.ViewGroup.layout(ViewGroup.java:4224)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.View.layout(View.java:11278)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.ViewGroup.layout(ViewGroup.java:4224)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.View.layout(View.java:11278)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.ViewGroup.layout(ViewGroup.java:4224)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.View.layout(View.java:11278)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.ViewGroup.layout(ViewGroup.java:4224)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.View.layout(View.java:11278)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.ViewGroup.layout(ViewGroup.java:4224)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1489)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.os.Handler.dispatchMessage(Handler.java:99)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.os.Looper.loop(Looper.java:137)
03-29 08:17:13.518: E/AndroidRuntime(1384): at android.app.ActivityThread.main(ActivityThread.java:4424)
03-29 08:17:13.518: E/AndroidRuntime(1384): at java.lang.reflect.Method.invokeNative(Native Method)
03-29 08:17:13.518: E/AndroidRuntime(1384): at java.lang.reflect.Method.invoke(Method.java:511)
03-29 08:17:13.518: E/AndroidRuntime(1384): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
03-29 08:17:13.518: E/AndroidRuntime(1384): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
03-29 08:17:13.518: E/AndroidRuntime(1384): at dalvik.system.NativeStart.main(Native Method)