Runtime DrawerLayout must be measured with Measure

2020-02-12 04:32发布

问题:

I'm following this tutorial from and I'm facing with a strange problem.

It doesn't matter what's in my DrawerLayout, but if its layout_height or layout_width are set to anything other than hardcoded number, it throws this runtime exception.

I've seeing plenty of reports of this error thrown when trying to render an output in the Graphical Layout tool, but couldn't find any on a runtime error.

I have the latest support library, updated just now to version 21.0.2

I would like to avoid hardcoding my height and width if possible.

The beginning of the file looks like this. This way, it crushes.

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

and the stacktrace is

12-04 00:57:51.051: E/AndroidRuntime(26254): FATAL EXCEPTION: main
12-04 00:57:51.051: E/AndroidRuntime(26254): Process: com.lablabla.homedestroyer, PID: 26254
12-04 00:57:51.051: E/AndroidRuntime(26254): java.lang.IllegalArgumentException: DrawerLayout must be measured with MeasureSpec.EXACTLY.
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:814)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.View.measure(View.java:17430)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.View.measure(View.java:17430)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.View.measure(View.java:17430)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2560)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.View.measure(View.java:17430)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2001)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1141)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1372)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5779)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.Choreographer.doCallbacks(Choreographer.java:580)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.Choreographer.doFrame(Choreographer.java:550)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.os.Handler.handleCallback(Handler.java:739)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.os.Handler.dispatchMessage(Handler.java:95)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.os.Looper.loop(Looper.java:135)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at android.app.ActivityThread.main(ActivityThread.java:5221)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at java.lang.reflect.Method.invoke(Native Method)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at java.lang.reflect.Method.invoke(Method.java:372)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
12-04 00:57:51.051: E/AndroidRuntime(26254):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

If it has to be hardcoded, what's the best way to make it "right" for various screen sizes?

回答1:

Try overriding the DrawerLayout's on measure method

public class CustomDrawerLayout extends DrawerLayout {

public CustomDrawerLayout(Context context) {
    super(context);
}

public CustomDrawerLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public CustomDrawerLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    widthMeasureSpec = MeasureSpec.makeMeasureSpec(
            MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY);
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(
            MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.EXACTLY);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

}


回答2:

I found putting requestWindowFeature(Window.FEATURE_NO_TITLE); before setContent() could solve this in my case.