Runtime DrawerLayout must be measured with MeasureSpec.EXACTLY excpetion

La bla bla picture La bla bla · Dec 4, 2014 · Viewed 9.1k times · Source

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?

Answer

wolfaviators picture wolfaviators · May 18, 2015

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);
}

}