【问题标题】:What do you need to pass to v4.widget.DrawerLayout.isDrawerOpen()/.openDrawer()/.closeDrawer()您需要将什么传递给 v4.widget.DrawerLayout.isDrawerOpen()/.openDrawer()/.closeDrawer()
【发布时间】:2013-11-29 15:52:12
【问题描述】:

我一直在尝试按照 android here 的建议将我的代码移动到 DrawerLayout,因为 SlidingDrawer 已弃用。

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

isDrawerOpen() 方法描述为here:

公共布尔 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

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

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

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

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

【问题讨论】:

    标签: android navigation-drawer drawerlayout


    【解决方案1】:

    答案是:

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

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

    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>
    

    【讨论】:

    • 是的。如果您查看DrawerLayout 的源代码,isDrawerOpen(...) 方法会调用isDrawer(...) 以检查View 它被传递的是一个抽屉。标准是检查View 是否具有layout_gravityGravity.LEFTGravity.RIGHT。 “开始”layout_gravity 是一个别名,可用于确定抽屉固定在哪一侧。对于 RTL(从右到左)语言,它将是 Gravity.RIGHT,对于 LTR 语言,它是 Gravity.LEFT。如果没有为 View 设置这些,isDrawer(..) 方法将返回 false。
    • 谢谢你!就我而言,我对使用哪种重力感到困惑。不是android:gravity,而是android:layout_gravity
    • 哇,因为我忘记了layout_gravity,所以这一直对我不起作用。如果可以的话 +10。
    【解决方案2】:

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

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

    mDrawerLayout.isDrawerOpen(Gravity.START);
    

    作为 mDrawerLayout 对您的 DrawerLayout 的引用。

    如你所说,别忘了android:layout_gravity="start"

    【讨论】:

      【解决方案3】:

      在您的 Activity 中,如果您有对 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)。

      【讨论】:

        【解决方案4】:

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

        closeDrawers()
        

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

        【讨论】:

          猜你喜欢
          • 2021-06-07
          • 1970-01-01
          • 1970-01-01
          • 2016-03-20
          • 1970-01-01
          • 2011-03-14
          • 2020-03-12
          • 2023-04-01
          • 1970-01-01
          相关资源
          最近更新 更多