Home » Android » android – Change actionbar to overlay from within Fragment

android – Change actionbar to overlay from within Fragment

Posted by: admin June 15, 2020 Leave a comment

Questions:

I have a fragment (Fragment 1) that is replaced by another fragment (Fragment 2). Fragment 1 is placed on the stack. I’m using compatibility mode (not ActionBarSherlock).

Here’s my problem. I want the actionbar to be displayed as overlay in some fragments, but not in others. Specifically, when Fragment 2 is shown, I want it to appear in overlay and then go back to the normal actionbar once Fragment 2 exits.

Fragment 1 has an regular actionbar that is always visible. But, when I replace Fragment 1 with Fragment 2, I need to hide the actionbar after 5 seconds. If there is a touch event, the actionbar is shown again. This all works fine, but, Fragment 2 is redrawn each time the actionbar is hidden or revealed. Because of this, I want to make the actionbar in Fragment 2 show as an overlay.

I know I can change the actionbar overlay but I don’t know how to do that programmatically from within the fragment. I DON’T want to change it for every fragment, just Fragment 2.

Ideas?????

How to&Answers:

This may not be the answer you were hoping for.

Consider a different question: Can we change activity theme after setContentView(...) has been called? The question has been asked many times, and a common solution is to recreate(calling finish() and startActivity(getIntent())) the activity and set the new theme before setContentView(...).

Your question is an extension to this – with added complexity of changing the theme from a fragment. In any case, I don’t consider the solution mentioned above a good one.

ActionBar is one of the first components to be initialized when an Activity is created. I don’t think you will find a way to somehow ‘refresh’ it with new attributes. See below how the requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY) method deals with post-setContentView(…) calls:

@Override
public boolean requestFeature(int featureId) {
    if (mContentParent != null) {
        throw new AndroidRuntimeException("requestFeature() must be 
                                                       called before adding content");
    }
    ....
    ....
}

So, if setContentView(...) has already been called for the Activity (which it is, in your case), a runtime-exception will be thrown.

Is it possible that you don’t even require this functionality?

Start by setting the ActionBar to be an overlay in your theme:

<item name="android:windowActionBarOverlay">true</item>
<!-- Support library attribute for compatibility -->
<item name="windowActionBarOverlay">true</item>

Here’s my problem. I want the actionbar to be displayed as overlay in some fragments…

Okay. We have already provisioned for this above.

… but not in others.

Say you don’t want to have the ActionBar as an overlay in Fragment B. Then, in Fragment B’s layout, do the following:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="?android:attr/actionBarSize" >  <<<-- ?attr/actionBarSize
                                                                    for compatibility

    ....
    ....
</LinearLayout>

With the top-margin set to ActionBar’s size, Fragment B looks as if it has a regular ActionBar – not an overlaid one. Another way to achieve this would be to have a View with android:layout_height="?android:attr/actionBarSize" placed as the first child in the layout above.

In essence:

  • your ActionBar will be an overlay.
  • in the fragments where the ActionBar will auto-hide, the fragments layout will not have any top-margin set.
  • in the fragments where the ActionBar should not be overlaid, the fragments layout will have top-margin set to actionBarSize.

A point of note (thanks to Jelle):

If your ActionBar is semi-transparent, it would be best to use padding instead of margin for a consistent look.