19

我正在尝试将 DrawerLayout 添加到我的应用程序以进行导航,并且正在使用 Robolectric 测试我的应用程序(我在 Robolectric 2.1.1 和 2.1-SNAPSHOT - 2.2-20130712.161723-17 中都看到了这个问题)

我正在使用以下 xml 作为抽屉布局的基础。当我在抽屉布局上将 andioid:layout_width 或 android:layout_height 设置为“match_parent”时,我在 Robolectric 中遇到错误。

<?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>

这是我遇到的错误的堆栈跟踪:

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)

我尝试将这些设置为硬编码值(例如 400dp),这样可以解决测试中的问题。但是,我无法让我的手机上安装的应用程序的宽度和高度为 match_parent。有什么方法可以设置我的 Robolectric 设备的宽度和高度?或者有没有人遇到过这个问题并想出了一些其他的解决方法?

它似乎与这个问题有关:https ://code.google.com/p/android/issues/detail?id=55611 注意,这个问题的另一个副作用是设计视图被破坏了。

4

3 回答 3

30

经过一番挖掘,我找到了解决方案。似乎 Robolectric 以某种方式错误地计算了 MeasureSpec,从而导致了这个问题。就我而言,我可以通过扩展 DrawerLayout 并覆盖 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);
    }

}
于 2013-07-26T17:22:07.280 回答
0

更新您的支持库 jar:http: //developer.android.com/tools/support-library/setup.html

并确保您的项目引用的是最新的:How do I add a library (android-support-v7-appcompat) in IntelliJ IDEA

库的示例路径:[adt-bundle-windows]\sdk\extras\android\support\v4\android-support-v4.jar

于 2014-01-05T15:52:27.277 回答
0

只需在你的安卓设备上运行你的程序。它运行完美。我猜只是Eclipse中的一些问题。

于 2014-10-27T09:37:23.407 回答