In Robolectric, how do I get around DrawerLayout must be measured with MeasureSpec.EXACTLY error?

坚强是说给别人听的谎言 提交于 2019-11-29 06:07:15

问题


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.


回答1:


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

}



回答2:


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




回答3:


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



来源:https://stackoverflow.com/questions/17687173/in-robolectric-how-do-i-get-around-drawerlayout-must-be-measured-with-measuresp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!