Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using navigationView with tabLayout

So I've recently been working on updating my app to use the new material design support library. My application has one main activity with a drawerLayout and navigation view. The main content of app is shown in a frameLayout, through fragments. However, I am trying now to add material tabs to one of the navigation drawer's fragments. However, I am not sure how to implement this while keeping my fragments in the nav drawer functioning. A good example of what I am trying to achieve is shown below:

enter image description here

In this app (Google play music), only some of the navigation drawer's items have tabs while others do not. So my question is, how would I implement this? (Not looking for code, just an overview of how my layout should be organized)

To recap/clarify: I have a main layout with a frameLayout (for my app's content), and a navigationView (for navigating the different item fragments). I then have a listener which replaces the main layout's frameLayout with the item's respective fragment. Now, I need to add tabs to just one of these fragments (to navigate between 4 other fragments). I am also using a toolbar which I include as a separate layout.

Any advice is appreciated. I'm sorry if my description is a little confusing; I will clarify any necessary details.

like image 664
mlz7 Avatar asked Aug 26 '15 23:08

mlz7


2 Answers

Ok suppose your NavigationView has two options, the first one displays the fragment with tabs (tab layout) and the second one displays just a fragment with a toolbar. You have two options then:

  1. You can have a main layout with just a frame layout and replace it with all what you want
  2. You can have a main layout with coordinator layout -> app bar -> toolbar -> tab layout and a frame layout to put content

I prefer the second option to avoid having to always configure the toolbar so this is what I did once:

<!-- layout_main -->
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.CoordinatorLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.v7.widget.Toolbar                    
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_scrollFlags="scroll|enterAlways"/>

            <android.support.design.widget.TabLayout
                android:id="@+id/tab_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="gone"
                app:tabGravity="fill"
                app:tabMode="fixed" />

        </android.support.design.widget.AppBarLayout>

        <FrameLayout
            android:id="@+id/main_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    </android.support.design.widget.CoordinatorLayout>

    <!-- The NavigationView -->
    <fragment
        android:id="@+id/navigation_fragment"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:name="some.path.to.the.NavigationViewFragment"
        tools:layout="@layout/fragment_navigation_view" />

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

As you see I change the visibility of TabLayout to "gone" so that the fragment with tabs take care to set as visible. The Fragment with the tabs just have the ViewPager in the Layout:

<!-- fragment_with_tabs -->
<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Now the fragment with tabs initialize the ViewPager with the fragments for each page:

@Override 
public onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    // The getChildFragmentManager() is Very important! Because fragments inside fragments are
    // not supported with the tipical fragmentManager, it requires NestedFragments and those
    // uses a childFragmentManager(). In other case a strange behaviour occurs
    ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
    adapter.addFragment(new TabOneFragment(), "Tab 1");
    adapter.addFragment(new TabTwoFragment(), "Tab 2");
    viewPager.setAdapter(adapter);

    tabLayout = (TabLayout) getActivity().findViewById(R.id.tab_layout);
    tabLayout.setVisibility(View.VISIBLE);
    tabLayout.setupWithViewPager(viewPager);
}

And finally do whatever you want in your TabFragments, this works fine for me and I hope this be useful for you too. Sorry for some problem with code syntax, I develop android with Kotlin and not with Java.

like image 194
Yiyo Castillo Avatar answered Oct 06 '22 02:10

Yiyo Castillo


I can't recommend what Yiyo suggested. If you are going to have Fragments with different layouts, you should let the Fragments customize these layouts in the XML. This is why the introduction of Toolbar made so much sense for Android development. In the future, you might even have more requirements that differ between each Fragment. Some of them might not want a Toolbar, some of them might need another View above the Toolbar, some of them will have a RecyclerView that you would like to be accessible to the CoordinatorLayout and AppBar so that the scrolling behavior works properly.

I recommend you to put only a FrameLayout as the content of your DrawerLayout (as Yiyo mentioned in point 1). Here you will load each Fragment from the callbacks of the NavigationView.

<android.support.v4.widget.DrawerLayout 
    ...
    android:fitsSystemWindows="true"
    >

    <FrameLayout
        android:id="@+id/drawer_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <android.support.design.widget.NavigationView
        ...
        />

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

In each Fragment's XML you will put, if required by that Fragment, a Toolbar. In your tabbed Fragment's XML you will put the TabLayout, and if you so wish, the CoordinatorLayout and AppBarLayout. From each Fragment that has a Toolbar, you will set the Toolbar as the ActionBar:

Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setSupportActionBar(toolbar);

That's all there is to it. Of course you don't want to repeat yourself in every Fragment, so you can, for example, put this code in a DrawerFragment and subclass it for fragments with a Toolbar. You will also want to put your Toolbar XML configuration in a single file and include it in the Fragment's XML <include layout="@layout/toolbar" />. Or you might want to remove the Toolbar from some fragments, or change its color, theme, etc.

like image 20
sorianiv Avatar answered Oct 06 '22 02:10

sorianiv