Saat men-debug metode onMeasure()
tampilan kustom yang diganti, saya melihat ada beberapa panggilan ke metode ini.
Saya hanya berurusan dengan tinggi tampilan, membiarkan spesifikasi lebar selalu tidak berubah.
Pada titik tertentu saya mendapat panggilan dengan MeasureSpec (tinggi) getMode()
== EXACTLY
dan getSize()
== 0.
Ini tidak masuk akal dan bertentangan dengan dokumentasi 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.
Jika saya melakukan seperti yang diharapkan (Anak harus menggunakan ukuran ini), setMeasureDimension(specWidth, sepcHeight)
Saya mendapat pengecualian yang menyatakan lebar dan tinggi tampilan harus > 0.
Saya menduga panggilan ini disebabkan karena dalam tata letak XML, tampilan memiliki layout_weight="1"
dan, menurut dokumentasi saran:
Untuk membuat tata letak linier yang setiap turunannya menggunakan jumlah ruang yang sama di layar, setel android:layout_height setiap tampilan ke "0dp"
Namun tetap saja, ketika mode MeasureSpec adalah EXACTLY, ukurannya harus > 0. Atau setidaknya harus ada beberapa aturan yang harus diikuti dalam kasus ini, dalam dokumentasi.
ini kodenya:
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);
Ini lognya, catat panggilan terakhir ke 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)