Search code examples
androidandroid-layoutandroid-activityandroid-studioandroid-navigationview

How to have a navigation view load in multiple activities without bugs?


I created a navigation view (Note: the newer navigation view, not a older navigation drawer which is setup differently) followed the guide found here. I set it to open a new activity, were I just repeated the code again but changed the class and intent statements to reflect the current activity. (changed main activity extends to activity2 extends, etc) but when I do that the text view in main activity shows up in activity2 also and ignores the textview in activity2.

so how exactly can I set this up to have the navigation view be displayed in all my activities without copying code dozens of times and each activity having there own textview? also i am a novice android programmer so saying "supposed to use a fragment" or something similar, I need code examples to actually understand what I need to do (again, please don't refer me to navigation drawer samples as this is set up differently)


Solution

  • I suggest you use simple scheme - one Activity, many Fragments.

    For example - you can create new project in Android studio with Navigation Drawer Activity (although it says "Navigation Drawer" in the new versions of Android studio activity will be created with NavigationView) - it will create one MainActivity for you.

    For supporting Fragments scheme, you need special container on your Activity for content of this fragments. Let's add FrameLayout into layout/content_main.xml file:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout 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:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:context=".MainActivity"
        tools:showIn="@layout/app_bar_main">
    
        <!-- The main content view -->
        <FrameLayout
            android:id="@+id/content_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </RelativeLayout>
    

    Note, that I created FrameLayout with content_frame id - we will use it later.

    Then, for example, create two blank fragments - BlankFragment1 and BlankFragment2.

    And now look on code in MainActivity, but rather on onNavigationItemSelected method. By default, it looks like:

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();
    
        if (id == R.id.nav_camara) {
            // Handle the camera action
        } else if (id == R.id.nav_gallery) {
    
        } else if (id == R.id.nav_slideshow) {
    
        } else if (id == R.id.nav_manage) {
    
        } else if (id == R.id.nav_share) {
    
        } else if (id == R.id.nav_send) {
    
        }
    
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }
    

    Each if statement helps us to distinguish the menu items in the navigation view. Let's change this code to go away toBlankFragment1 by clicking on R.id.nav_camara and go away to BlankFragment2 by clicking on R.id.nav_gallery:

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
    
        Fragment fragment;
        switch (item.getItemId()) {
            case R.id.nav_camara:
                fragment = BlankFragment1.newInstance("param1", "param2");
                break;
    
            case R.id.nav_gallery:
                fragment = BlankFragment2.newInstance("param3", "param4");
                break;
    
            default:
                fragment = BlankFragment1.newInstance("param1", "param2");
        }
    
        // Insert the fragment by replacing any existing fragment
        FragmentManager fragmentManager = this.getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.content_frame, fragment)
                .commit();
    
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }
    

    And launch the app. Now, you can change your fragments by clicking on this two icons (camera and gallery). Hope it helps you.