119

I have ActionBarActivity with NavigationDrawer and use support_v7 Toolbar as ActionBar. In one of my fragments toolbar has custom view. In other fragments Toolbar should show title.

How get Toolbar instance for customizing from fragments? I can get ActionBar with getActivity().getActionBar(), but if I call setTitle() for this instance ActionBar it do nothing.

UPD:

In my case

((ActionBarActivity) getActivity()).getSupportActionBar().setTitle();

(as MrEngineer13 said) don't work at first fragment creation because I call it from onHiddenChanged(). Now I add more one to onCreateView() and it works fine.

mmBs
  • 8,421
  • 6
  • 38
  • 46
anisart
  • 1,747
  • 2
  • 13
  • 15

10 Answers10

221

You need to cast your activity from getActivity() to AppCompatActivity first. Here's an example:

((AppCompatActivity) getActivity()).getSupportActionBar().setTitle();

The reason you have to cast it is because getActivity() returns a FragmentActivity and you need an AppCompatActivity

In Kotlin:

(activity as AppCompatActivity).supportActionBar?.title = "My Title"
Anonsage
  • 8,030
  • 5
  • 48
  • 51
MrEngineer13
  • 38,642
  • 13
  • 74
  • 93
  • 9
    getting 'supportActionBar' and 'toolbar' is same thing? – Darpan Mar 15 '16 at 11:34
  • @Darpan not sure – Konstantin Konopko May 15 '17 at 17:11
  • If i add this, its changing the title.. But if i go back to the parent activity, how to change the title again ? I mean i have a nav drawer. Side drawer has some fragments and main activity has its own title. When i set title of main activity, it works and in fragment, the way you mentioned worked perfect. But how should i change the title of the activity on going back? – Kylo Ren Oct 15 '18 at 11:09
85

In case fragments should have custom view of ToolBar you can implement ToolBar for each fragment separately.

add ToolBar into fragment_layout:

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimaryDark"/>

find it in fragment:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment, container, false);
        Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);

        //set toolbar appearance
        toolbar.setBackground(R.color.material_blue_grey_800);

        //for crate home button
        AppCompatActivity activity = (AppCompatActivity) getActivity();
        activity.setSupportActionBar(toolbar);
        activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

menu listener could be created two ways: override onOptionsItemSelected in your fragment:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch(item.getItemId()){
        case android.R.id.home:
            getActivity().onBackPressed();
    }
    return super.onOptionsItemSelected(item);
}

or set listener for toolbar when create it in onCreateView():

toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                return false;
            }
        });
Oleksandr B
  • 3,400
  • 1
  • 25
  • 28
  • 1
    I just want confirm this the right way to do? if we load different fragment with toolbar in viewpager+ Tablayout or Pagertabstripe it will effect the app performance while swiping? – LOG_TAG Jul 14 '15 at 09:41
  • 1
    @LOG_TAG I have a drawer design with each fragment implementing the toolbar (and thus having a toolbar in it's layout file) and the above code worked great for me. – MattBoothDev Jul 23 '15 at 14:22
  • Thanks! Worked like HEYUL!! :) Btw, better to override parent Activity's `onOptionsItemSelected()` instead of Fragment's, to avoid code repetition. – Aditya Naique Sep 16 '15 at 04:33
  • @ChadMx no, why he even wrote about adding toolbar in xml and so on. Author asked how to get toolbar programmatically from fragment . So http://stackoverflow.com/a/26998718/4548520 this is the best/right answer and it's short – user25 Aug 27 '16 at 08:05
51

You have two choices to get Toolbar in fragment

First one

Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);

and second one

Toolbar toolbar = ((MainActivity) getActivity()).mToolbar;
Bhargav Thanki
  • 4,924
  • 2
  • 37
  • 43
  • But is this the right way .. bcoz we have getSupportedActionBar also ? – Code_Life Aug 23 '16 at 05:48
  • 2
    If you are using a one-activity-to-many-fragments model, the first example simply gets you a reference to the main toolbar so you can manipulate it from your fragment. It is also, I believe, the best option. – Trasd Aug 24 '20 at 17:59
10
toolbar = (Toolbar) getView().findViewById(R.id.toolbar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setSupportActionBar(toolbar);
mmBs
  • 8,421
  • 6
  • 38
  • 46
Danial
  • 451
  • 6
  • 17
2

From your Fragment: ( get Toolbar from fragment?)

// get toolbar
((MainAcivity)this.getActivity()).getToolbar();  // getToolbar will be method in Activity that returns Toolbar!!  don't use getSupportActionBar for getting toolbar!!
// get action bar
this.getActivity().getSupportActionBar();

this is very helpful when you are using spinner in Toolbar and call the spinner or custom views in Toolbar from a fragment!

From your Activity:

// get toolbar
this.getToolbar();
// get Action Bar
this.getSupportActionBar();
LOG_TAG
  • 19,894
  • 12
  • 72
  • 105
  • 3
    You have to have a method in your activity called **getToolbar()**, which is bad, because that is not how communication between activity and fragment should be done. – Marko Jul 17 '15 at 07:46
  • 2
    yes there is no other way for this!! many of the navigation drawer libs implement this style only !!! some times we need cast the activity because of AppCompatActivity (AppCompatActivity) getActivity() that is another pain point !!! all this stuffs totally kills the dev time :( – LOG_TAG Jul 17 '15 at 08:58
2

For Kotlin users (activity as AppCompatActivity).supportActionBar?.show()

Muhamed Riyas M
  • 5,055
  • 3
  • 30
  • 31
1

Maybe you have to try getActivity().getSupportActionBar().setTitle() if you are using support_v7.

Wang
  • 1,028
  • 7
  • 12
1

I did it by using these steps.

  1. Set Title using below code in onCreateView of the main fragment.
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Your title");

  1. For swapping between fragments i'm using bottom navigation bar which is implemented on MainActivity (Parent Activity) of the fragment. Even if you are using any button or menu item then you can change the title from onSelectedItemClickListener, just like i did in my case.
    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
        switch (menuItem.getItemId()){
            case R.id.menu_dashboard:
                getSupportActionBar().setTitle("Dashboard");
                fm.beginTransaction().hide(active).show(dashboardFragment).commit();
                active = dashboardFragment;
                return true;
            case R.id.menu_workshop:
                getSupportActionBar().setTitle("Workshops");
                fm.beginTransaction().hide(active).show(workshopFragment).commit();
                active = workshopFragment;
                return true;
         }
         return false;
    }
    
1

In XML

 <androidx.appcompat.widget.Toolbar
  android:id="@+id/main_toolbar"
  android:layout_width="match_parent"
  android:layout_height="?attr/actionBarSize"
  app:layout_scrollFlags="scroll|enterAlways">
 </androidx.appcompat.widget.Toolbar>

Kotlin: In fragment.kt -> onCreateView()

setHasOptionsMenu(true)

val toolbar = view.findViewById<Toolbar>(R.id.main_toolbar)

(activity as? AppCompatActivity)?.setSupportActionBar(toolbar)

(activity as? AppCompatActivity)?.supportActionBar?.show()

-> onCreateOptionsMenu()

   override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
       inflater.inflate(R.menu.app_main_menu,menu)
       super.onCreateOptionsMenu(menu, inflater)
   }

->onOptionsItemSelected()

   override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
             R.id.selected_id->{//to_do}
             else -> super.onOptionsItemSelected(item)
        }
    }
Priom Khan
  • 11
  • 2
0

if you are using custom toolbar or ActionBar and you want to get reference of your toolbar/action bar from Fragments then you need to first get instance of your Main Activity from Fragment's onCreateView Method like below.

MainActivity activity = (MainActivity) getActivity();

then use activity for further implementation like below

ImageView vRightBtn = activity.toolbar.findViewById(R.id.toolbar_right_btn);

Before calling this, you need to initialize your custom toolbar in your MainActivity as below.

First set define your toolbar public like

public Toolbar toolbar;
public ActionBar actionBar;

and in onCreate() Method assign the custom toolbar id

toolbar = findViewById(R.id.custom_toolbar);
setSupportActionBar(toolbar);
actionBar = getSupportActionBar();

That's It. It will work in Fragment.

mdubey
  • 1
  • 4