如何在没有操作栏的情况下打开导航抽屉,只需使用按钮打开

43
我是一名有用的助手,可以翻译文本。

我有一个没有任何操作栏的导航栏(我不想要操作栏)。我正在尝试创建一个按钮,可以打开导航抽屉。

我知道有一个叫做openDrawer的方法可以打开DrawerLayout http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html#openDrawer(android.view.View)

我不知道如何使用它,但我已经尝试制作一个按钮,当点击时运行此方法:

DrawerLayout mDrawerLayout = (DrawerLayout) getView().findViewById(R.id.drawer_layout);
mDrawerLayout.openDrawer(mDrawerLayout);

当我点击它时,它会给我一个Java空指针异常。有人有什么想法吗?
编辑: 这段代码在一个片段中,我正在尝试引用那些抽屉布局到片段外面。我使用调试器,它显示mDrawlerLayout为空。
有什么建议吗?
谢谢!
7个回答

56

您之所以收到空指针,是因为您试图在片段的视图中查找抽屉布局,而实际上它在活动视图中。

快速解决此问题的方法是通过以下方式查找视图:

getActivity().findViewById(R.id.drawer_layout)

那应该可以工作。更好的方法是在活动中拥有一个打开抽屉的方法。

public void openDrawer(){
    mDrawerLayout.openDrawer(mDrawerLayout);
}

在activity的onCreate方法中运行findViewById方法:
mDrawerLayout = (DrawerLayout) getView().findViewById(R.id.drawer_layout);

mDrawerLayout应该是您活动的成员变量。

然后在您的片段中,您可以调用:

//cast activity to MyActivity so compiler doesn't complain
((MyActivity)getActivity()).openDrawer();

更好的方法是在片段中创建一个监听器,并将活动设置为该片段的监听器。然后,您可以调用类似上面的方法来调用活动上的方法。我会让您自行研究如何实现这一点。

15
我在openDrawer方法中必须使用mDrawerLayout.openDrawer(Gravity.LEFT);才能使它正常工作。(我正在使用没有片段和操作栏的导航抽屉)否则,它会使应用程序挂起。 - Ashish Tanna
是否可以删除默认图标?我想在那个位置使用不同的选项菜单。 - JCarlosR

40
drawerLayout.openDrawer(Gravity.START);

4

它在按钮点击时起作用

mButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            drawer.openDrawer(GravityCompat.START);

        }
    });

2
感谢@athor和@Ashish Tana。
我花了很多时间才找出我遇到的错误(NullPointerException)。
我的方法是这样的:不使用getView(),而是使用getActivity(),并通过mDrawerLayout.openDrawer(Gravity.LEFT)打开抽屉。
mDrawerLayout = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
final ImageButton btnOpenDrawer = (ImageButton) getView().findViewById(R.id.drawer_menu);

        btnOpenDrawer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mDrawerLayout.openDrawer(Gravity.LEFT);
            }
        });

这真的有效,我将其放置在onCreate(Bundle savedInstanceState)中: super.onCreate(savedInstanceState); //在此处放置代码 - Faisal

2

我有一个更简单的解决方案,它使用了DrawerLayoutisDrawerOpen()方法。

下面的代码会根据导航抽屉的当前状态(打开/关闭)来关闭或打开导航抽屉:

Button hamMenu = findViewById(R.id.ham_menu);
hamMenu.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        DrawerLayout navDrawer = findViewById(R.id.drawer_layout);
        // If navigation drawer is not open yet, open it else close it.
        if(!navDrawer.isDrawerOpen(GravityCompat.START)) navDrawer.openDrawer(Gravity.START);
        else navDrawer.closeDrawer(Gravity.END);
    }
});

为了关闭抽屉,我不得不使用 navDrawer.closeDrawer(Gravity.START) 才能让它正常工作。否则,我只会收到一个 IllegalArgumentException 错误,提示“没有找到右侧的抽屉视图”。 - Denis Francia Karell
为了关闭抽屉,我必须使用navDrawer.closeDrawer(Gravity.START);才能使其正常工作。否则,我会收到一个“IllegalArgumentException”错误,因为“没有找到右侧引力的抽屉视图”。 - undefined

0

我在这里写了一个关于此的答案:https://dev59.com/BHXYa4cB1Zd3GeqP6nv6#18199771

   //For me a better way in avoiding a `null pointer` in getting the DrawerLayout
   final DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
   btn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                            //Opens the Drawer
                drawer.openDrawer(Your View, Usually a ListView);
            }

                return false;
        });

你可以直接在视图/片段中获取当前的抽屉,这样就不会出现NullPointerException


0

Kotlin 解决方案
如果你想从一个 fragment 中打开它,你可以使用以下代码:

activity?.drawerLayout?.openDrawer(GravityCompat.START)

或者直接在活动中:

drawerLayout.openDrawer(GravityCompat.START)

注意:
如果您不熟悉'?',我强烈建议阅读Kotlin文档中有关空安全的内容(它非常简短,不用担心):https://kotlinlang.org/docs/reference/null-safety.html

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接