HOW TO Revert Action Bar after Switching Fragments

aindurti

Problem:

The Fragment backstack is made so that traversing backwards through a stack of fragments in one activity does not revert the Action Bar to its original state in the previous fragment.

Why does this happen?

Turns out, the Action Bar is actually attached to the Activity itself, not the fragment! Remember, fragments are only modular bits of the UI, and have to explicitly specify control to other fragments, sections of the activity, or even the Action Bar.

Keep reading for the solution...

aindurti

Solution:

I found that the best approach to this problem is done by what is generally described in Reto Meier's answer to a previous question. My solution will just expand more deeply on his answer.

What we want to establish though is that we don't want to re-create the action bar every time we switch to a different fragment, reason being it's not very efficient. I'm going to walk you through an I wrote for a student scheduling app. It's not very complicated, and it's onboarding experience is composed of multiple fragments held within an activity.

To make this work, we need to make sure we're using replace() to switch between fragments. This is better than layering fragments on top of each other, because it lets you configure the action bar separately for each fragment.

The first chunk of code comes from the activity's inner class, LoginOptionsFragment, in its onCreateView() method.

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_login_options, container, false);
        //LoginOptionsFragment will have its own action bar
        setHasOptionsMenu(true);
        //inject views. e.g: Button add_course
        ButterKnife.inject(this, rootView);

        add_course.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getFragmentManager().beginTransaction()
                        //exchange fragments. no messy clean-up necessary.
                        .replace(R.id.container, new AddCourseFragment())
                        .addToBackStack(null)
                        .commit();
            }
        });

        return rootView;
    }

Here, I not only make sure to call onCreateOptionsMenu() via the setHasOptionsMenu(true), but mainly, as soon as the "ADD COURSE" button is clicked to switch to the AddCourseFragment, the new fragment replaces the old fragment as the primary child of the activity. Next, after we override the onCreateOptionsMenu(), we come to onResume(), but we'll get to that later ;)

Secondly, we arrive at the AddCourseFragment, where we even inflate a custom done-cancel view for the action bar. So let's look at the code!

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // BEGIN_INCLUDE (inflate_set_custom_view)
        // Inflate a "Done/Cancel" custom action bar view.
        final ActionBar actionBar = getActivity().getActionBar();
        inflater = (LayoutInflater) actionBar.getThemedContext()
                .getSystemService(LAYOUT_INFLATER_SERVICE);

        //inflate custom action bar view
        View customActionBarView = inflater.inflate(
                R.layout.actionbar_custom_view_done_cancel, null);

        //set listeners to items in the view
        customActionBarView.findViewById(R.id.actionbar_done).setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                    // "Done"
                        //remove custom view from action bar
                        actionBar.setDisplayShowCustomEnabled(false);
                        getFragmentManager().popBackStack();
                        //add course to list
                    }
                });
        customActionBarView.findViewById(R.id.actionbar_cancel).setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                    // "Cancel"
                        //remove custom view from action bar
                        actionBar.setDisplayShowCustomEnabled(false);
                        getFragmentManager().popBackStack();
                    }
                });

        // Show the custom action bar view and hide the normal Home icon and title.
        actionBar.setDisplayOptions(
                ActionBar.DISPLAY_SHOW_CUSTOM,
                ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME
                        | ActionBar.DISPLAY_SHOW_TITLE);
        actionBar.setCustomView(customActionBarView,
                new ActionBar.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT));
        actionBar.setDisplayHomeAsUpEnabled(false);
        // END_INCLUDE (inflate_set_custom_view)

        View rootView = inflater.inflate(R.layout.fragment_add_course, container, false);
        ButterKnife.inject(this, rootView);

        return rootView;
    }

The ONLY part that you need to pay attention to are the OnClickListener's added to the DONE and CANCEL buttons. In here, I use my previous reference to the parent Activity's action bar and tell it to stop displaying the custom view. Now in addition to this specific method, there are more setDisplayXEnabled() methods that you can pass in false to. After that, I pop the backstack to get to the previous fragment.

But how do I actually revert the action bar!?

Here's how. Remember that onResume() method that was hanging out in our LoginOptionsFragment? Well, onResume() is called once a fragment gets back into focus from the backstack! So if we override it and re-enable the parts of the action bar that we want, we win right? Yes we do. Here is all you need to add into the onResume().

@Override
    public void onResume() {
        super.onResume();
        ActionBar actionBar = getActivity().getActionBar();
        actionBar.setDisplayShowHomeEnabled(true); //show Home icon
        actionBar.setDisplayShowTitleEnabled(true); //show title
//      actionBar.setDisplayUseLogoEnabled(true); <--- more options
//      actionBar.setDisplayHomeAsUpEnabled(true); <--- more options
    }

And we did it all without recreating the action bar. Here's how it looks!

output

Thanks for reading, and happy coding!

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Debian: How to revert back to KDE after switching to GNOME?

From Dev

How to dynamically set number of swipeable tabs in Action Bar with Fragments at runtime

From Dev

Action Bar in Fragments - Tablets and Phones

From Dev

Action Bar in Fragments - Tablets and Phones

From Dev

RecyclerView items disappear after switching between fragments

From Dev

How to reset Action Bar Search after Searching?

From Dev

How to revert to legacy switching layout method?

From Dev

How to revert to legacy switching layout method?

From Dev

How to get back menu bar in Kile after switching to LXDE?

From Dev

Center aligning of title in action bar of activity and fragments

From Dev

Invalidate Contextual Action Bar on When Switching Tabs

From Dev

My Navigation bar is not switching between fragments in Android Studio Kotlin

From Dev

How to handle camera while switching between fragments?

From Dev

Show progress bar after an action

From Dev

Managing Action Bar titles when using fragments and the backstack

From Dev

Increment action bar View Badger on button click by using fragments

From Dev

Up Navigation (Action Bar's back arrow) is not working for fragments

From Dev

Hide/Show Action Bar Option Menu Item for different fragments

From Dev

Managing Action Bar titles when using fragments and the backstack

From Dev

Implementing back navigation in action bar in nested fragments with navigation drawer?

From Dev

How to add action bar

From Dev

How to customize action bar

From Dev

How to manage app bar when using fragments?

From Dev

How to manage app bar when using fragments?

From Dev

Git: how to revert after a merge conflict corruption

From Dev

Switching between Fragments with button

From Dev

Switching fragments in navigation drawer

From Dev

No error in logcat but fragments are not switching

From Dev

Switching fragments in navigation drawer

Related Related

  1. 1

    Debian: How to revert back to KDE after switching to GNOME?

  2. 2

    How to dynamically set number of swipeable tabs in Action Bar with Fragments at runtime

  3. 3

    Action Bar in Fragments - Tablets and Phones

  4. 4

    Action Bar in Fragments - Tablets and Phones

  5. 5

    RecyclerView items disappear after switching between fragments

  6. 6

    How to reset Action Bar Search after Searching?

  7. 7

    How to revert to legacy switching layout method?

  8. 8

    How to revert to legacy switching layout method?

  9. 9

    How to get back menu bar in Kile after switching to LXDE?

  10. 10

    Center aligning of title in action bar of activity and fragments

  11. 11

    Invalidate Contextual Action Bar on When Switching Tabs

  12. 12

    My Navigation bar is not switching between fragments in Android Studio Kotlin

  13. 13

    How to handle camera while switching between fragments?

  14. 14

    Show progress bar after an action

  15. 15

    Managing Action Bar titles when using fragments and the backstack

  16. 16

    Increment action bar View Badger on button click by using fragments

  17. 17

    Up Navigation (Action Bar's back arrow) is not working for fragments

  18. 18

    Hide/Show Action Bar Option Menu Item for different fragments

  19. 19

    Managing Action Bar titles when using fragments and the backstack

  20. 20

    Implementing back navigation in action bar in nested fragments with navigation drawer?

  21. 21

    How to add action bar

  22. 22

    How to customize action bar

  23. 23

    How to manage app bar when using fragments?

  24. 24

    How to manage app bar when using fragments?

  25. 25

    Git: how to revert after a merge conflict corruption

  26. 26

    Switching between Fragments with button

  27. 27

    Switching fragments in navigation drawer

  28. 28

    No error in logcat but fragments are not switching

  29. 29

    Switching fragments in navigation drawer

HotTag

Archive