onNavigationItemSelected方法未被调用

21

我在我的应用程序中实现了一个NavigationView,这是由AndroidStudio自动生成的。当我创建新项目时,我选择了NavigationDrawer Activity,菜单项看起来没问题,但是当我点击任何一个菜单项时没有反应。 以下是我的onNavigationItemSelected()方法:

@Override
public boolean onNavigationItemSelected(MenuItem item) {
    Toast.makeText(MainActivity.this,"onNavigationItemSelected",Toast.LENGTH_LONG).show();
    // Handle navigation view item clicks here.
    item.setChecked(true);
    int id = item.getItemId();

    if (id == R.id.medicalRecord) {
        Toast.makeText(MainActivity.this,id,Toast.LENGTH_LONG).show();
    } 

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

在我的onCreate方法中,我创建了一个NavigationView。

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linear_layout);
    if (babyImage.exists()) {
        Drawable drawable = Drawable.createFromPath(Environment.getExternalStorageDirectory() + "/babycare/temp.jpg");
        linearLayout.setBackground(drawable);
    }

    DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawerLayout.openDrawer(Gravity.LEFT);
    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
}

当然,我已经为我的类实现了NavigationView.OnNavigationItemSelectedListener。

我正在想是否应该在Material Design主题中实现此NavigationView。现在我的应用程序使用的主题是@style/AppTheme

请有人帮我解决这个问题,谢谢。

6个回答

35

我解决了我的问题,只需要简单地更改我的activity_main.xml中的顺序。

我有一个LinearLayout视图组和DrawerLayout视图组中的NavigationView,在最开始时NavigationView是视图组中的第一个,现在我改变了顺序,第一个是LinearLayout,第二个是NavigationView,并且它按照预期工作。亲爱的!!!

但是,有人能告诉我为什么会发生这种情况吗?在视图组中的视图顺序是否重要,不管显示顺序如何?


我也遇到了同样的问题。按照解决方案操作后,问题得到了解决。 - jgm
你有任何想法为什么顺序会导致这样的影响吗? - Nick Su
1
我不知道为什么会这样。显然根据你的解决方案,它可以工作。 - jgm
我遇到了同样的问题,这个方法对我也起作用了。谢谢@NickSu。 - Mahdi
1
谢谢分享。看起来NavigationView应该是布局中最后一个视图。 - Hadi Nahavandi
显示剩余3条评论

20

我也遇到了这个问题,最后终于找出了问题所在。我最初创建了一个带有导航抽屉的示例项目,其中主要活动的 XML 如下所示:

<include
    layout="@layout/app_bar_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_main"
    app:menu="@menu/activity_main_drawer" />

但是在我实际制作的应用程序中,我犯了这样一个错误,

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_main"
    app:menu="@menu/activity_main_drawer" />

<LinearLayout...../>
</android.support.v4.widget.DrawerLayout>

我的问题出在NavigationView下面的LinearLayout。

后来我修改了这个问题,然后一切都开始正常工作了。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">

<LinearLayout...../>

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_main"
    app:menu="@menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>

关键在于将NavigationView放在最后。奇怪的是UI没有受到干扰,但回调函数出了问题。


对我有用。我想值得接受这个答案。文档中没有提到这一点,有点荒谬。感谢您指出这一点! - ThePartyTurtle
1
这是因为 NavigationView 必须具有更高的 z 值,以便在滑出时它可见于视图层次结构的顶部。XML 布局从排序中获取其 z 值,xml 中的最后一个视图具有最高的 z 值。 - AndroidDev
我也试过了,肯定与z值有关。非常感谢! - Luigi_Papardelle

16

导航抽屉帮助文档中指出:

主内容视图 (上面的 FrameLayout) 必须是 DrawerLayout 中的第一个子级,因为 XML 的顺序意味着 z-顺序,而抽屉必须在内容之上。

关于这个示例的建议:

<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="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111"/>
</android.support.v4.widget.DrawerLayout>

所以这就是解释,有点烦人的是,如果由于自动生成的模板导致布局顺序错误,你会遇到这种"问题"。我在使用Android Studio时几次遇到过这种情况,感到非常沮丧。


6
我是一个有用的助手,可以为您翻译文本。

我刚遇到了这个问题,但没有一个答案能帮助我。但最终我解决了。 在我的情况下,监听器没有被调用,因为我在我的活动中使用了:

NavigationUI.setupWithNavController(navigationView, navController);

这将覆盖我的 OnNavigationItemSelectedListener,所以我删除了那行代码,并将我的监听器设置为以下内容:

final NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(new 
NavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            FragmentManager fm = getSupportFragmentManager();
            fm.popBackStackImmediate();
            boolean handled = NavigationUI.onNavDestinationSelected(item, navController);
            if (handled) {
                ViewParent parent = navigationView.getParent();
                if (parent instanceof DrawerLayout) {
                    ((DrawerLayout) parent).closeDrawer(navigationView);
                }
            }
            return handled;
        }
    });

这里有一段NavigationUI代码,覆盖了我的监听器:

public static void setupWithNavController(@NonNull final NavigationView navigationView,
        @NonNull final NavController navController) {
    navigationView.setNavigationItemSelectedListener(
            new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                    boolean handled = onNavDestinationSelected(item, navController);
                    //******* CUTTED ***************
                    return handled;
                }
            });
}

我希望它能够帮助。


1

导航抽屉帮助中提到:

主内容视图(即上面的FrameLayout)必须是DrawerLayout中的第一个子元素,因为XML顺序意味着z-ordering,而抽屉必须在内容之上。

针对此示例:

<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="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111"/>
</android.support.v4.widget.DrawerLayout>

如果由于自动生成的模板而导致错误的布局顺序,那会很烦人。我在使用Android Studio时遇到过这种“问题”,非常令人沮丧。

-1

你应该改变标签的位置。不应该先使用NavigationView。这样会起作用。


最好在你的回复中包含“已经修改的”代码片段,而不是暗示修复方法。 - MoMo

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