25

我一直在尝试将我的代码移至DrawerLayoutandroid此处建议的SlidingDrawer已弃用的代码。

我的问题是,到目前为止DrawerLayout,它的实现似乎要么非常糟糕,要么有无用的错误消息(没有防御性编程)和/或文档中解释得不够好。

isDrawerOpen()方法在这里描述:

public boolean isDrawerOpen(查看抽屉)

检查给定的抽屉视图当前是否处于打开状态。要被视为“打开”,抽屉必须处于完全可见的状态。要检查部分可见性,请使用 isDrawerVisible(android.view.View)。

参数:drawer - 要检查的抽屉视图

返回:如果给定的抽屉视图处于打开状态,则返回 true

每个方法isDrawerOpen(View drawer)openDrawer(View drawer)并且closeDrawer(View drawer)在通过时都不起作用:DrawerLayout有问题的或其中任何一个的孩子。我不知道我应该为这些方法提供什么以使它们发挥作用。有人可以告诉我吗?

有关实施的完整问题描述,请参见下文。

我有这样的布局:

<android.support.v4.widget.DrawerLayout
    android:id="@+id/mainmenuPanel"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        android:id="@+id/dualPane"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <FrameLayout
        android:id="@+id/menuPane"
        android:layout_width="300dp"
        android:layout_height="match_parent" />
</android.support.v4.widget.DrawerLayout>

在我的代码中,我将以下方法连接到一个按钮:

protected void onCreate(Bundle savedInstanceState) {    
    ...
    mMenuPanel = (DrawerLayout) findViewById(R.id.mainmenuPanel);
    ....
}

public boolean isDrawerOpen() {
    if(mMenuPanel != null) {
        return mMenuPanel.isDrawerOpen(mMenuPanel);
    }
    return false;
}

但是,如果您将其本身作为参数(这在极端情况下是多余的),则会出现以下错误:

E/AndroidRuntime(11241): java.lang.ClassCastException: 
android.widget.FrameLayout$LayoutParams cannot be cast to 
android.support.v4.widget.DrawerLayout$LayoutParams

(你会注意到,它没有给你任何关于你做错了什么的信息。而是问题的一个症状)。

这里这里的其他答案要么难以理解,要么与问题密切相关,没有太多解释。即便如此,我还是尝试添加一个假的LinearLayout或一个DrawerLayouts 孩子,每个都给出这个错误:

E/AndroidRuntime(11424): java.lang.IllegalArgumentException: 
View android.widget.FrameLayout{420f5ea8 V.E..... ........ 
0,0-800,1172 #7f060038 app:id/menuPane} is not a drawer

谁能解释这些方法实际上需要传递给他们才能工作?

4

4 回答 4

19

而且,答案是:

第二个孩子(又名“抽屉”)是需要传递给方法的。我的问题是,当我发现我已经将布局简化为尽可能简单的测试实现时——我已经从“抽屉”中移除了重力。如果没有重力,您会收到上述完全不相关的错误消息。

我可以使用以下设置确认我的代码可以正常工作:

mMenuPanel.isDrawerOpen(findViewById(R.id.drawer));

和布局:

<android.support.v4.widget.DrawerLayout
    android:id="@+id/mainmenuPanel"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <FrameLayout
        android:id="@+id/drawer"
        android:layout_width="300dp"
        android:layout_height="match_parent" 
        android:layout_gravity="start"/> <!-- This line was the problem!!!!!!!-->
</android.support.v4.widget.DrawerLayout>
于 2013-11-29T15:58:15.040 回答
14

如果您想避免引用视图或布局以调用isDrawerOpen,则可以应用另一种方法。

在这种情况下,您必须指出重力:

mDrawerLayout.isDrawerOpen(Gravity.START);

作为mDrawerLayout对您的 DrawerLayout 的引用。

正如你所说,不要忘记android:layout_gravity="start"

于 2014-04-11T10:51:36.740 回答
2

在您的活动中,如果您有对 DrawerLayout 的引用,在这种情况下,您也可以使用 ID 为 R.id.menuPane 的 FrameLayout...

DrawerLayout mMenuPanel = (DrawerLayout) findViewById(R.id.mainmenuPanel);
FrameLayout mMenuPane = (FrameLayout) findViewById(R.id.menuPane);
mMenuPanel.isDrawerOpen(mMenuPane);

基本上,您必须传入对在 DrawerLayout 中用作抽屉的视图的引用,无论如何,它始终是 mMenuPanel.getChildAt(1)。

于 2014-01-23T22:19:14.447 回答
-1

如果您使用支持库中的抽屉布局,正如我们从您的问题中看到的那样,还有以下方法:

closeDrawers()

这将关闭所有打开的抽屉(通常只有一个)。

于 2016-03-17T12:40:52.043 回答