Nick Su
Nick Su

Reputation: 673

onNavigationItemSelected not getting called

I have implemented a navigationview in my app , which was automatically created by AndroidStudio. I picked up the NavigationDrawer Activity when I created a new project and the menu items seem ok , but nothing happend when I click on any of the menu item . Below is my onNavigationItemSelected() method:

@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;
}

}

And my onCreate method , I create the NavigationView in it

    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);
}

Of course , I implemented the NavigationView.OnNavigationItemSelectedListener for my class .

I am wondering whether this NavigationView should be implement in Material Design theme or not . Now the theme used in my app is @style/AppTheme

Please , someone help me out , thank you

Upvotes: 21

Views: 14505

Answers (6)

Alessandro
Alessandro

Reputation: 4472

I've just had this problem but none of the answers help me. But finally I solved. In my case, the listener wasn't called because I used in my activity:

NavigationUI.setupWithNavController(navigationView, navController);

That overrides my OnNavigationItemSelectedListener, so I removed that line and I've setted my listener as the following:

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;
        }
    });

Here's a piece of NavigationUI that override my listener:

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;
                }
            });
}

I hope it can helps.

Upvotes: 6

Aydın Üzmez
Aydın Üzmez

Reputation: 45

you should change the place of tags. shouldn't do NavigationView first. it works.

Upvotes: -1

Satheesh
Satheesh

Reputation: 11276

I too had this issue and I finally figured out what was wrong, I initially created a sample project with navigation drawer and the main activity xml was as below,

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

But in the actual app I made I did a mistake like this,

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

I had a LinearLayout below the NavigationView which was the issue.

Then I did this, everything started to work fine.

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

Key was to put the NavigationView at last. Weird that UI was not disturbed but callback was.

Upvotes: 20

leobelizquierdo
leobelizquierdo

Reputation: 1668

The Navigation Drawer help say this:

The main content view (the FrameLayout above) must be the first child in the DrawerLayout because the XML order implies z-ordering and the drawer must be on top of the content.

regards to this example:

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

What is kind of annoying is if you have the wrong layout order as a result of an auto-generated template. I have faced this kind of "problems" with Android Studio a few times and is so fustrating.

Upvotes: 1

leobelizquierdo
leobelizquierdo

Reputation: 1668

The Navigation Drawer help say this:

The main content view (the FrameLayout above) must be the first child in the DrawerLayout because the XML order implies z-ordering and the drawer must be on top of the content.

regards to this example:

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

So this is the explanation, what is kind of annoying is if you have the wrong layout order as a result of an auto-generated template. I have faced this kind of "problems" with Android Studio a few times and is so fustrating.

Upvotes: 16

Nick Su
Nick Su

Reputation: 673

I solved my question , just simply change the order in my activity_main.xml . I have a LinearLayout viewgroup and NavigationView in my DrawerLayout viewgroup , at first the NavigationView is the first in my viewgroup and now I change the order , the first one is the LinearLayout and the second is NavigationView , and it work as it suppose to be . Dear!!!

But can someone tell me why it happend ? Does it matter the view order in a viewgroup regardless the display sequence .

Upvotes: 35

Related Questions