Change actionbar to overlay from within Fragment

前端 未结 1 916
迷失自我
迷失自我 2021-01-05 04:09

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).

相关标签:
1条回答
  • 2021-01-05 04:51

    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.

    0 讨论(0)
提交回复
热议问题