15

I have a problem with my fragments. Basically, I have an app which has a navigation drawer and 4 buttons on the activity. When each button is pressed, it will display another fragment. The problem I have is that I want to display the correct title on the ActionBar. I can display the selected item from the navigation on the ActionBar. But when I pressed the button to go to another fragment, I cannot display the title on the ActionBar. Any ideas?

Here's my sample code: HomeActivity.class

 private void displayView(final int position) {
    // update the main content by replacing fragments
    Fragment fragment = null;
    switch (position) {
        case 0:
            fragment = new HomeFragment();
            break;
        case 1:
            fragment = new MyProfileFragment();
            break;
        case 2:
            fragment = new AboutFragment();
            break;
        default:
            break;
    }

    if (fragment != null) {
        fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.frame_container, fragment).commit();

        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        setTitle(navMenuTitles[position]);
        drawer.closeDrawer(mDrawerList);
    } else {
        // error in creating fragment
        Log.e("MainActivity", "Error in creating fragment");
    }

}

HomeFragment:

public class HomeFragment extends Fragment {

public HomeFragment() {
}

CardView card_cart, card_scan, card_categories, card_about;
Intent i;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_home, container, false);
    initControls(rootView);
    return rootView;
}

private void initControls(View rootView) {

    card_cart = (CardView) rootView.findViewById(R.id.card_cart);
    card_scan = (CardView) rootView.findViewById(R.id.card_scan);
    card_categories = (CardView) rootView.findViewById(R.id.card_categories);
    card_about = (CardView) rootView.findViewById(R.id.card_about);

    card_categories.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            i = new Intent(getActivity(), CategoriesActivity.class);
            startActivity(i);
        }
    });

    card_cart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            MyCartFragment nextFrag = new MyCartFragment();
            getFragmentManager().beginTransaction()
                    .replace(R.id.frame_container, nextFrag)
                    .addToBackStack(null)
                    .commit();
        }
    });

    card_about.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AboutGrabHutFragment aboutFrag = new AboutGrabHutFragment();
            getFragmentManager().beginTransaction()
                    .setBreadCrumbTitle(getResources().getString(R.string.about))
                    .replace(R.id.frame_container, aboutFrag)
                    .addToBackStack(null)
                    .commit();


        }
    });

    card_scan.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            i = new Intent(getActivity(), ScanActivity.class);
            startActivity(i);
        }
    });

}

In the HomeFragment will those 4 buttons be found. On a button click, will go to another fragment. I can display that using this:

card_about.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AboutGrabHutFragment aboutFrag = new AboutGrabHutFragment();
            getFragmentManager().beginTransaction()
                    .setBreadCrumbTitle(getResources().getString(R.string.about))
                    .replace(R.id.frame_container, aboutFrag)
                    .addToBackStack(null)
                    .commit();
            getActivity().setTitle("About");

        }
    });

But the problem is when I go back, the title is still About.

iknow
  • 8,358
  • 12
  • 41
  • 68
  • 1
    Look this link https://stackoverflow.com/a/46705242/1770868 – Ahmad Aghazadeh Oct 12 '17 at 08:52
  • for anyone that have stumbled here and using navigation drawer, your answer may be to update the your destination labels see this [question](https://stackoverflow.com/questions/54646720/how-to-change-label-attribute-of-a-destination-in-navigation-controller) – lasec0203 Oct 03 '19 at 13:59
  • There is another answer for that in this post. It is newer and takes care of the new ideas implemented lately as MVVM patterns. Please check this link: https://stackoverflow.com/a/18011671/9205277 – Dimitri Leite Jul 25 '20 at 00:06

4 Answers4

20

On the required fragment's onCreateView() method, call the setTitle("") method of your Main Activity. This way you don't event need to check for a back press event.

this worked for me

eg***

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.id.your_fragment_layout, container,
                false);
        getActivity().setTitle("Your actionbar title");

        return rootView;
    }

Update:

you can change the title by overriding the onResume method. And for the safe side, you can also override setUserVisibleHint and change the title when fragment isVisibleToUser.

Sachin Rao
  • 686
  • 5
  • 15
8

If someone uses Kotlin and @Sachin Rao answer doesn't work (like in my case) I made extensions functions to change title:

fun Fragment.setActivityTitle(@StringRes id: Int) {
    (activity as? AppCompatActivity)?.supportActionBar?.title = getString(id)
}

fun Fragment.setActivityTitle(title: String) {
    (activity as? AppCompatActivity)?.supportActionBar?.title = title
}

Usage (at any point in fragment):

setActivityTitle(R.string.title)
setActivityTitle("Title")
iknow
  • 8,358
  • 12
  • 41
  • 68
  • 1
    The code could be improved to: `(activity as? AppCompatActivity)?.supportActionBar?.title = title` so the app wouldn't crash if the activity doesn't implement `AppCompatActivity` – BladeCoder Aug 19 '22 at 10:41
3

I used a onBackStackChangedListener in my MainActivity and use it to update al kinds of stuff when you navigate in the app. You're already manually changing the title so try something like this :

//manager is my FragmentManager
manager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            //I'm using this check to check if i'm on my MainFragment, you can use this in al kinds of ways. Decide yourself if you use it or not.
            if (manager.getBackStackEntryCount() == 1) {
                Class<? extends Fragment> FragClass;
                //mCurrentFragment is my global Fragment variable to do and check stuff with as below.
                FragClass = mCurrentFragment.getClass();
                if ((FragClass == DesiredFragment.class)) {
                    this.setTitle("desired title");
                } else if ((FragClass == OtherDesiredFragment.class)) {
                    //hope this helps.
                } //etc..
            }
        }
    });
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
    try {
        Class<? extends Fragment> FragClass;
        FragClass = mCurrentFragment.getClass();
        if ((FragClass == HomeFragment.class)) {
            System.exit(0);
        }
            popFragment();
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
}

public void popFragment() {
    try {
        if (manager.getBackStackEntryCount() > 1) {
            manager.popBackStack();
            manager.executePendingTransactions();
            ArrayList<Fragment> reversedFragments = new ArrayList<Fragment>(manager.getFragments());
            Collections.reverse(reversedFragments);
            for (Fragment fragment : reversedFragments) {
                if (fragment != null) {
                    try {
                        mCurrentFragment = (BaseFragment) fragment;
                    } catch (ClassCastException e) {
                        e.printStackTrace();
                    }
                    break;
                }
            }
        } else {
            finish();
        }
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
}
Jordi Sipkens
  • 595
  • 1
  • 9
  • 25
1

None of the answers worked for me, what worked was setting the label in mobile_navigation.xml (the navigation xml file)

    android:label="@string/title_library"
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
user330844
  • 872
  • 1
  • 12
  • 12