19

I'm trying to add a DrawerLayout to my application for navigation, and I'm testing my application with Robolectric (I've seen this problem both with Robolectric 2.1.1 and 2.1-SNAPSHOT - 2.2-20130712.161723-17)

I'm using the following xml for the base of my drawer layout. I encounter the error in Robolectric when I have the andioid:layout_width or android:layout_height set to be "match_parent" on the Drawer Layout.

<?xml version="1.0" encoding="utf-8"?>
<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">
    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <!-- The navigation drawer -->
    <ListView android:id="@+id/left_drawer"
        android:layout_width="250dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="#D8D8D8"
        android:dividerHeight="1dp"
        android:background="#F2F2F2"/>
</android.support.v4.widget.DrawerLayout>

Here's the stack trace of the error I'm encountering:

java.lang.IllegalArgumentException: DrawerLayout must be measured with MeasureSpec.EXACTLY.
    at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:591)
    at android.view.View.measure(View.java:15172)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4816)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
    at android.view.View.measure(View.java:15172)
    at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1850)
    at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1102)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1275)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4214)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
    at android.view.Choreographer.doCallbacks(Choreographer.java:555)
    at android.view.Choreographer.doFrame(Choreographer.java:525)
    at android.view.Choreographer$FrameHandler.handleMessage(Choreographer.java:657)
    at org.robolectric.shadows.ShadowHandler.routeMessage(ShadowHandler.java:125)
    at org.robolectric.shadows.ShadowHandler.access$100(ShadowHandler.java:25)
    at org.robolectric.shadows.ShadowHandler$1.run(ShadowHandler.java:110)
    at org.robolectric.util.Scheduler$PostedRunnable.run(Scheduler.java:162)
    at org.robolectric.util.Scheduler.runOneTask(Scheduler.java:107)
    at org.robolectric.util.Scheduler.advanceTo(Scheduler.java:92)
    at org.robolectric.util.Scheduler.advanceToLastPostedRunnable(Scheduler.java:68)
    at org.robolectric.util.Scheduler.unPause(Scheduler.java:25)
    at org.robolectric.shadows.ShadowLooper.unPause(ShadowLooper.java:219)
    at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:258)
    at org.robolectric.shadows.ShadowViewGroup.addView(ShadowViewGroup.java:32)
    at android.view.ViewGroup.addView(ViewGroup.java)
    at android.view.ViewGroup.addView(ViewGroup.java:3225)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:497)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
    at org.robolectric.tester.android.view.RoboWindow.setContentView(RoboWindow.java:82)
    at org.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:273)
    at android.app.Activity.setContentView(Activity.java)
    at com.taskrabbit.droidrabbitstaging.TRRootDrawerActivity.onCreate(TRRootDrawerActivity.java:35)
    at com.taskrabbit.droidrabbitstaging.ui.routes.EmptyRouteActivity.onCreate(EmptyRouteActivity.java:34)
    at com.taskrabbit.droidrabbitstaging.ui.routes.EmptyRouteActivityTest.setUp(EmptyRouteActivityTest.java:62)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:241)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:177)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

I've tried setting these to a hard-coded value (of say 400dp) and that clears up the problems in the test. However, I then have trouble getting the width & height to be match_parent for my app installed on my phone. Is there any way that I can set the width and height of my Robolectric device? Or has anyone encountered this and come up with some other work around?

It appears to be related to this issue: https://code.google.com/p/android/issues/detail?id=55611 Note, the other side effect of this issue is that Design View is broken.

Hilary Karls
  • 243
  • 2
  • 7
  • what if you extend the DrawerLayouout and ensure that MesureSpecs are forced to be correct... if will try that, since I ran in the same issue – joecks Jul 26 '13 at 15:56

3 Answers3

30

After some digging, I found a solution. It seems that Robolectric is somehow misscalculating the MeasureSpecs, which leads to this issue. In my case I could fix this problem by extending the DrawerLayout, and overriding onMeasure() :

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

}
joecks
  • 4,539
  • 37
  • 48
  • 3
    I just found your answer joecks... ran into this trying to start an intent from a fragment that was part of a drawerlayout view... driving me nuts.. Thank you so much! – Evan R. Sep 04 '13 at 04:41
  • This is remains a problem at runtime problem, even though Google claims to have fixed this in Android Support Library revision 19 (October 2013). This hack works much better than my previous hack. – DataGraham Nov 14 '13 at 17:17
0

Update your Support Library jar: http://developer.android.com/tools/support-library/setup.html

And make sure that your project refers the latest one: How do I add a library (android-support-v7-appcompat) in IntelliJ IDEA

Example path to the lib: [adt-bundle-windows]\sdk\extras\android\support\v4\android-support-v4.jar

Community
  • 1
  • 1
Pavel Shkleinik
  • 6,298
  • 2
  • 24
  • 36
0

Just run your program on your android device. It runs perfectly. Just some problem in Eclipse i guess.

Sagar Shah
  • 391
  • 5
  • 11