Edge to Edge Theme for Background of Android Activity to Hide Status Bar Scrim During Fragment Transitions

285 Views Asked by At

I have 1 activity that hosts multiple fragments in a navHostFragment. To switch between them I use androids Navigation Component (i.e. navGraph).

Now I want to enable edge-to-edge. I already have it working in the static case, but during transitions (think Navigation Drawer switching or animation during a FAB click event) there seems to be a (activity?) theme in the background that still uses a bluish colors for the status bar scrim.

During navigation drawer switching it is visible only for a short amount of time, giving it a flickering impression.

The FAB action takes longer, revealing the blue status bar color unacceptable long, see second attached picture.

The order of the transition is following:

  • First dashboard fragment disappears, revealing the blue status bar
  • Second blank fragment begins to scale up
  • Second blank fragment covers the status bar
  • Second blank fragment is fully scaled up, blue status bar sits "underneath" it

NOTE - The used and shown container transform transition isn't ready yet, forget about the strange looking fab and blue container (the fab transition isn't relevant for the blue status bar issue, as the issue also appears e.g. for a millisecond during initial app start-up).

Question

So I guess it boils down to how to define and set an activity theme which changes the status bar color (either to transparent or e.g. the surface color) and teach Android to use it from the first start.

Right now I use

<!--values/themes.xml -->
<style name="Base.Theme.App" parent="Theme.Material3.DayNight.NoActionBar">

and for v29

<!--v29/themes.xml -->
    <style name="Theme.App" parent="Base.Theme.App">
        <item name="android:statusBarColor">@android:color/transparent</item>
</style>

and manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
 ...
        android:theme="@style/Theme.App"
        tools:targetApi="34">
        <activity
            android:name=".ui.uielements.activities.MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

enter image description hereenter image description hereenter image description here

1

There are 1 best solutions below

0
citizen_code On

It seems deleting the android:fitsSystemWindows="true" on the activity_main.xml root element (in my case a drawer layout) did the trick.

This shows clearly that I still don't understand WHY and WHAT android:fitsSystemWindows="true" does (after reading and watching EVERYTHING about it) so feel free to comment...

Anyway edge to edge is hard on android :/


Some context to my set-up (only things that matter for edge to edge are included):

Enable edge to edge:

MainActivity.kt

 override fun onCreate(savedInstanceState: Bundle?) {
        enableEdgeToEdge()
        super.onCreate(savedInstanceState)
        ...
}

activity_main.xml

<androidx.drawerlayout.widget.DrawerLayout 
...>

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:fitsSystemWindows="true"
     ...>     <!-- here I removed the "fitsSystemWindows="true" flag -->

        <androidx.fragment.app.FragmentContainerView
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:fitsSystemWindows="true"
         .../>

        <com.google.android.material.floatingactionbutton.FloatingActionButton
         .../>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

    <com.google.android.material.navigation.NavigationView
        android:fitsSystemWindows="true"
     .../>

</androidx.drawerlayout.widget.DrawerLayout>

First Fragment (second equivalent): dashboard_fragment_xml

<androidx.coordinatorlayout.widget.CoordinatorLayout
    android:fitsSystemWindows="true"
    ...>

    <include
        android:id="@+id/app_bar_layout"
        layout="@layout/default_appbar"/>

    <androidx.core.widget.NestedScrollView
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">

    </androidx.core.widget.NestedScrollView>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

default_appbar_xml

<com.google.android.material.appbar.AppBarLayout
    android:fitsSystemWindows="true"
    ...>

    <com.google.android.material.appbar.MaterialToolbar 
     ... />

</com.google.android.material.appbar.AppBarLayout>

with a theme.xml of

<!--v29/themes.xml -->
    <style name="Theme.App" parent="Base.Theme.App">
        <item name="android:navigationBarColor">@android:color/transparent</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
        <item name="android:windowLightStatusBar">?attr/isLightTheme</item>
    </style>
</style>