How to handle drawer toggle and toolbar up when having toolbar for each fragment
Asked Answered
C

6

12

I am using single activity and many fragments approach in my app

Now since in my some fragments I have custom view in toolbar I decided to have separate toolbar for each fragment.

How to implement separate toolbar for each fragment also the drawer layout is in my activity Home page category page

Coff answered 11/12, 2017 at 19:25 Comment(2)
Have you found any solution?Cagey
no not found any solutionCoff
C
4

I have the same problem, I will add custom toolbar view for each fragment.

My Utility method is:

public static View addRemoveViewFromToolbar(FragmentActivity fragmentActivity, int resourceId) {
    Toolbar toolbar = removeViewFromToolbar(fragmentActivity);
    if (resourceId == 0) {
        return null;
    } else {
        View view = LayoutInflater.from(fragmentActivity).inflate(resourceId, toolbar, false);
        toolbar.addView(view);
        return view;
    }
}


public static Toolbar removeViewFromToolbar(FragmentActivity fragmentActivity) {
    Toolbar toolbar = (Toolbar) fragmentActivity.findViewById(R.id.toolbar);
    if (toolbar.getChildCount() > 1) {
        for (int i = 1; i <= toolbar.getChildCount(); i++) {
            toolbar.removeViewAt(1);
        }
    }
    return toolbar;
}

In my each fragment

//Create your custom view based on requirement
    View view = Utility.addRemoveViewFromToolbar(getActivity(), R.layout.toolbar_search_view);
        if (view != null) {
            edtCategory1 = (EditText) view.findViewById(R.id.edtCategory1);
            edtCategory1.setOnClickListener(this);
        }

Hope this explanation help you :)

Cagey answered 14/12, 2017 at 15:5 Comment(0)
R
0

I'm not sure if I understood your description of the your app correctly, but I recently did what I think you described. My activity layout was a DrawerLayout with an included CoordinatorLayout/AppBar layout with a single toolbar and a FrameLayout below. The menu.xml contained all the items I needed in my toolbar for all the fragments. Items clicked in the nav menu would swap out fragments in the FrameLayout. My onNavigationItemSelected() called on this method to swap out the fragments and handle the backstack:

 public void switchView(int id, int optArg) {
   if (currentView != id) {
     currentView = id; //currentView keeps track of which fragment is loaded
     FragmentTransaction transaction = getFragmentManager().beginTransaction();
     //Fragment contentFragment is the current fragment in the FrameLayout
     switch (id) {
       case 0: //menu item 1
         contentFragment = new Nav_Item1_Fragment();
         transaction.replace(R.id.fragment_container, contentFragment, "");
         break;
       case 1: //menu item 2
         contentFragment = new Nav_Item2_Fragment();
         transaction.replace(R.id.fragment_container, contentFragment, "");
         break;
       case 2: //menu item 3
         contentFragment = new Nav_Item3_Fragment();
         transaction.replace(R.id.fragment_container, contentFragment, "");
       break;
     }
     // Replace whatever is in the fragment_container view with this fragment,
     // and add the transaction to the back stack
     // transaction.replace(R.id.fragment_container, contentFragment);
     transaction.addToBackStack(null);
     // Commit the transaction
     transaction.commit();
   }
 }

and in each fragment's onPrepareOptionsMenu() I setVisible() hid/showed the menu items in the toolbar related to that fragment. Each item had an method in the activity pointed to by the menu item's onClick attribute that knew what fragment it was from and what views were passed to it.

The drawer was setup in the onCreate() of the activity with a ActionBarDrawerToggle like so:

drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
        this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();

activity xml:

<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    ...>

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

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

app_bar_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    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.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:gravity="top"
            .../>

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

    <FrameLayout
        android:id="@+id/fragment_container"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
    </FrameLayout>

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

So...One Nav menu, one App/Tool Bar, multiple fragments

Romanticist answered 12/12, 2017 at 4:27 Comment(1)
no this is not I want I want toolbar for each fragment and want to handle drawer toggle at the same timeCoff
I
0

Why do you specifically want a separate toolbar for each fragment? You can easily change the toolbar view for each fragment.

In your function to switch fragments -

public void selectDrawerItem(MenuItem item) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction;
        switch (item.getItemId()) {

                    case R.id.nav_home :
                        getSupportActionBar().setCustomView(R.layout.home_nav_bar);
                        fragmentClass = HomeFragment.class;
                        break;
                    case R.id.nav_settings :
                        getSupportActionBar().setCustomView(R.layout.settings_nav_bar);
                        fragmentClass = SettingsFragment.class;
                        break;

        }
        fragment = (Fragment) fragmentClass.newInstance();
        fragmentManager.popBackStack(null, 
        FragmentManager.POP_BACK_STACK_INCLUSIVE);

        fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.replace(R.id.fragment_container, fragment);
                fragmentTransaction.addToBackStack(null);
                fragmentTransaction.commit();
}

So you can easily use the same toolbar and customize it according to your requirements for each fragment.

Iaria answered 14/12, 2017 at 14:28 Comment(2)
I want to use separate toolbar for each fragment please read question againCoff
Can you please explain why you want to use a separate toolbar? Using custom view is like using a separate toolbar. If you are still adamant on separate toolbar, the only option I can think of is to create multiple instances of ActionBarDrawerToggle with the toolbar instance you want like - ActionBarDrawerToggle toggle1 = new ActionBarDrawerToggle( this, drawerLayout, toolbar1, R.string.navigation_open, R.string.navigation_close); And then before loading the fragment you want, drawerLayout.addDrawerListener(toggle1); This is not tested. So let me know if it works.Iaria
B
0

It can be done in a quite straightforward way.

  1. First create an activity with a drawerlayout.

  2. Second create a container viewpager inside the activity to hold the fragments

  3. Third implement a listener on your viewpager that will set the relevant toolbar based on the fragment on display.

Let me illustrate by relevant XMLs and code

First the Drawerlayout XML for the main activity

    <?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">
<include
    layout="@layout/app_bar_landing_page"
    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_landing_page"
    app:menu="@menu/activity_landing_page_drawer" />

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

Please note the container layout app_bar_landing_page. Now the XML for this

 <?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
    tools:context="me.veganbuddy.veganbuddy.ui.LandingPage">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:elevation="4dp"
            app:logo="@drawable/vegan_buddy_menu_icon"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

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

    <android.support.v4.view.ViewPager
        android:id="@+id/container_for_fragments"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>

Note the viewpager which will act as container for fragments. Now the OnPageChangeListener on the viewpager.

mViewPager = (ViewPager) findViewById(R.id.container_for_fragments);
    mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            switch (position+1){
                case 0:setSupportActionBar(aToolbar);
                    break;
                case 1:setSupportActionBar(bToolbar);
                    break;
                case 2:setSupportActionBar(cToolbar);;
                    break;
                case 3:setSupportActionBar(dToolbar);
                    break;
                default:
                    break;
            }
        }

Let me know if any further clarification is needed

Beggary answered 19/12, 2017 at 15:53 Comment(0)
P
0

The simplest approach I would suggest is to use callbacks to activity. Whenever each fragment loads in the activity, arrange a callback to the activity and load the appropriate toolbar in the activity.

Have separate toolbar xmls in your layout folder. Use the include tag to put the toolbars in your activity. Keep only 1 toolbar visible at a time. When the fragment callbacks come to your activity make the necessary one visible.

Pals answered 21/12, 2017 at 6:58 Comment(0)
M
0

It's very simple. Besides the onclick action for the Category fragment is taking you into a new activity, not a Fragment. Now, since drawer layout is in parent activity with navigation view and without toolbar then in the first drawer fragment is a tablayout having four tabs with viewpager and a toolbar on the top and inside one tab i.e HOME is the TOP CHARTS, CATEGORIES, EDITORS. Each toolbar must be implemented in each fragment layout and not in the activity layout since you want different toolbars for each fragment. Note that Toolbar is not a property of Fragment but it's a property of ActionBarActivity or AppCompatActivity, then in the onCreateView, of the fragment that's holding the HOME, GAMES, MOVIES, MUSIC, put down these codes.

    public class Drawer1Fragment extends Fragment{
    public Drawer1Fragment () {}
    TabLayout tabLayout;
    Toolbar toolbar;
    DrawerLayout drawerLayout;
        ViewPager viewPager;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        View myChildRoot = inflater.inflate(R.layout.child_fragment_attachment, container, false);
        tabLayout = myChildRoot.findViewById(R.id.tab_layout);
        viewPager= myChildRoot.findViewById(R.id.container_viewPager);
        toolbar = myChildRoot.findViewById(R.id.toolbar);
        drawerLayout = getActivity().findViewById(R.id.drawer_layout);
        ((AppCompatActivity)requireActivity()).setSupportActionBar(toolbar);
        ((AppCompatActivity)requireActivity()).getSupportActionBar().setTitle(getActivity().getResources().getString(R.string.app_name));
        ((AppCompatActivity)requireActivity()).getSupportActionBar().setHomeButtonEnabled(true);
        ((AppCompatActivity)getParentFragment().requireActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(getActivity(),drawerLayout,toolbar,R.drawable.icons,R.string.app_name);
        drawerLayout.addDrawerListener(toggle);
        toggle.syncState();
// The back arrow of a toolbar in fragment is implemented below
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view)
            {
                if(!drawerLayout.isDrawerOpen(GravityCompat.START)) {
                    drawerLayout.openDrawer(GravityCompat.START);
                } else {
                    getActivity().finish();
                }
            }
        });
        
        return myChildRoot;
    }
}
Meantime answered 6/1, 2022 at 1:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.