What do you need to pass to v4.widget.DrawerLayout.isDrawerOpen()/.openDrawer()/.closeDrawer()

Graeme picture Graeme · Nov 29, 2013 · Viewed 9.4k times · Source

I've been trying to move my code across to the DrawerLayout as suggested by android here as SlidingDrawer is deprecated.

My problem is that so far DrawerLayout seems to be either very badly implemented, has unhelpful error messages (no defensive programming) and/or isn't explained well enough in the documentation.

the isDrawerOpen() method is described here:

public boolean isDrawerOpen (View drawer)

Check if the given drawer view is currently in an open state. To be considered "open" the drawer must have settled into its fully visible state. To check for partial visibility use isDrawerVisible(android.view.View).

Parameters: drawer - Drawer view to check

Returns: true if the given drawer view is in an open state

Each of the methods isDrawerOpen(View drawer), openDrawer(View drawer) and closeDrawer(View drawer) don't work when passed: The DrawerLayout in question or either of it's children. I have no idea what I'm supposed to feed into these methods to allow them to function. Can someone let me know?

See below for entire problem description with implementation.

I have a layout like so:

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

And in my code I have the following method hooked up to a button:

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

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

However if you give it itself as an argument (which would be redundant in the extreme) you get the following error:

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

(Which as you'll notice, doesn't give you any information about what you did wrong. It is instead a symtom of the problem).

Other answers here or here are either incomprehensible or very closely tied to the question without much explanation. Even so I've tried adding a faux LinearLayout or one the DrawerLayouts children and each give this error:

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

Can anyone explain what these methods actually need to have passed to them to work?

Answer

Graeme picture Graeme · Nov 29, 2013

And, the answer:

The second child (aka, the "Drawer") is what needs to be passed to the methods. My problem was that by the time I had figured that out I'd reduced the layout to as simple as possible implementation to test - I'd removed the gravity from the "drawer". Without a gravity, you get the above completely unrelated error messages.

I can confirm I got the code to work using the following setup:

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

and with the layout:

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