Using Toolbar with Fragments

101,661

Solution 1

Fragments don't have such method setSupportActionBar(). ActionBar is a property of Activity, so to set your toolbar as the actionBar, your activity should extend from ActionBarActivity and then you can call in your Fragment:

 ((ActionBarActivity)getActivity()).setSupportActionBar(mToolbar);

UPDATE

If you're using AppCompatActivity :

 ((AppCompatActivity)getActivity()).setSupportActionBar(mToolbar);

Solution 2

I have seen a lot of answers mentioning to setSupportActionBar for toolbar inside Fragment but this approach may go wrong if you are having a a toolbar in Activity and a separate Toolbar in Fragment.

  1. As you shift setSupportActionBar from Activity's Toolbar to Fragment's toolbar, You may face duplication of MenuItem even you try to override using setHasOptionsMenu(true).
  2. Secondly If you want to update Activity's Toolbar you see your changes are not reflected because of setSupportActionBar inside your Fragment.

So in order to avoid this I recommend to use toolbar methods like this inside fragment to inflate menu and use

 toolbar = (Toolbar) view.findViewById(R.id.toolbar_frag);
    toolbar.inflateMenu(R.menu.frag_menu_items);
    Menu menu = toolbar.getMenu();

and use Toolbar.OnMenuItemClickListener interface to receive with menuItems click events.

Edit (Section Copied from MrEngineer13 answer)

and if you are worried about the back button you can set it like this

toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_action_back));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       //What to do on back clicked
   }
});

Solution 3

Base on @Faisal Naseer answer. Here is the full example (with few notes) for using custom Toolbar with navigation and menu in Fragment

fragment_home.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"">

    ...
    <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar_home"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:title="Home" /> 

</androidx.constraintlayout.widget.ConstraintLayout>

HomeFragment.kt

class HomeFragment : BaseFragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        // setHasOptionsMenu(true): don't need this anymore
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_home, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        toolbar_home.setNavigationIcon(R.drawable.ic_back) // need to set the icon here to have a navigation icon. You can simple create an vector image by "Vector Asset" and using here
        toolbar_home.setNavigationOnClickListener {
            // do something when click navigation
        }

        toolbar_home.inflateMenu(R.menu.menu_home)
        toolbar_home.setOnMenuItemClickListener {
            when (it.itemId) {
                R.id.action_add -> {
                    // do something
                    true
                }
                R.id.action_update -> {
                    // do something
                    true
                }
                else -> {
                    super.onOptionsItemSelected(it)
                }
            }
        }
    }
}

menu_home.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/action_add"
        android:title="@string/add_device"
        app:showAsAction="never" />

    <item
        android:id="@+id/action_update_room"
        android:title="@string/update_room"
        app:showAsAction="never" />

</menu>

Hope it help

enter image description here

Solution 4

With the new AppCompatActivity you should call it instead of ActionBarActivity:

((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);

Solution 5

You can add toolbar in Fragments using this

 ((YOUR_ACTIVITY) getActivity()).getDelegate().setSupportActionBar(toolbar);
Share:
101,661
Al Hennessey
Author by

Al Hennessey

Updated on July 09, 2022

Comments

  • Al Hennessey
    Al Hennessey almost 2 years

    I am trying to create a viewpager that swipes through 3 different fragments each with a different toolbar. I have implemented the new toolbar in an activity before and got it to work however I am trying to get it to work with fragments

    Here is the fragment code

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout resource that'll be returned
        View rootView = inflater.inflate(R.layout.fragment_home, container, false);
    
    
        mToolbar = (Toolbar) rootView.findViewById(R.id.toolbar_home);
        if (mToolbar != null) {
            setSupportActionBar(mToolbar);
        }
        mToolbar.setTitle(null);
    
        return rootView;
    }
    

    I am extending my fragment with Fragment, however I am getting the error

    Cannot resolve method setSupportActionBar
    

    I am not sure how to resolve this, if I remove the setSupportActionBar code will it stop working with certain devices?

    • tachyonflux
      tachyonflux about 9 years
      Is there an issue with having it in your activity layout and setting it in your activity?
    • Al Hennessey
      Al Hennessey about 9 years
      each toolbar for each viewpager will have a different color and different menus, so i thought it would be better to control them with the fragments
    • MH.
      MH. about 9 years
      Hang on, isn't the whole point in this scenario not to set the ToolBar as ActionBar? Since your intention is for every fragment to have its own ToolBar (which swipes along with the other content of the fragment), we're talking about the 'standalone' (scroll down to the 'standalone' section) usage of the widget.
    • tachyonflux
      tachyonflux about 9 years
      The menu part is already supported with different menu xmls and attaching via onCreateOptionsMenu. The color part can be done within the onAttach using something like stackoverflow.com/questions/25081706/…
  • Roel
    Roel over 8 years
    In my case this does not replace the actionbar of the Mainactivity but it gives the Toolbar a title like in the Mainactivity.
  • Ram Mansawala
    Ram Mansawala over 8 years
    @vinitius Hey in your above answer you forgot to write "()" after getActivity. so please add this so other people will not get confuse.
  • Ness Tyagi
    Ness Tyagi over 6 years
    Hi Faisal Naseer can you explain it in detail becoz i m facing the same problem that you describe.
  • Faisal Naseer
    Faisal Naseer over 6 years
    sure whats the issue at your end have you tried the above approach.
  • Ness Tyagi
    Ness Tyagi over 6 years
    I have resolved the issue using your code by RND thanks for your feedback. Actually i have only one Activity and rest of all fragment in my app. So updating the toolbar with option menu in each fragment occur the issue. But with your code its working fine Thankyou.
  • Faisal Naseer
    Faisal Naseer over 6 years
    Shifting SupportActionBar from Activity's toolbar to Fragments toolbar may loose Support for Activity toolbar. what if you need to update the Activity toolbar once inside Fragment with shifted SupportActionBar ? :).
  • a-rohim
    a-rohim over 4 years
    Hi, the inflate menu working very well but setOnMenuItemClickListener doesn't work Need help.
  • akshay
    akshay almost 4 years
    even for single menu it shows overflow menu. I dont want overflow menu, what can done to achieve that?
  • iamkdblue
    iamkdblue almost 4 years
    how about if I don't wanna back arrow, how can I hide it?, I need only three dots
  • AndyBoy
    AndyBoy over 3 years
    @Phan, Where is BaseFragment can you provide me that also? Because toolbar_home is not finding here in this example.