maui
maui copied to clipboard
[Android] Apps compiled for 15.0 / 35 default displaying as Edge to Edge
Description
Starting with Android 15.0 (API 35) apps are displayed 'Edge to Edge' by default. https://developer.android.com/about/versions/15/behavior-changes-15#window-insets
It seems that .NET MAUI still adds content insets when using Shell but when using normal pages it does not. The result is that page content extends underneath the system bars (status and navigation) where it previously did not on older android versions.
There is a way to opting out of the new behaviour: https://medium.com/androiddevelopers/insets-handling-tips-for-android-15s-edge-to-edge-enforcement-872774e8839b
First, you need to add values-v35/styles.xml and values/styles.xml files:
In the values-v35/styles.xml declare a style:
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="OptOutEdgeToEdgeEnforcement">
<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
</style>
</resources>
You need to add a style with the same name in the values/styles.xml file (without the attribute):
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="OptOutEdgeToEdgeEnforcement">
</style>
</resources>
Now in your MainActivity.cs override the OnCreate(Bundle? savedInstanceState) and apply the style you created:
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
protected override void OnCreate(Bundle? savedInstanceState)
{
// Must apply the style before the DecorView setup
Theme?.ApplyStyle(Resource.Style.OptOutEdgeToEdgeEnforcement, force: false);
base.OnCreate(savedInstanceState);
}
}
Version with bug
9.0.0-rc.1.24453.9
Is this a regression from previous behavior?
No, this is something new
Last version that worked well
Android 14.0 and older
Affected platforms
Android
Affected platform versions
Android 15.0 / API 35
Hi I'm an AI powered bot that finds similar issues based off the issue title.
Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one and thumbs upping the other issue to help us prioritize it. Thank you!
Open similar issues:
- Shell Title View Overlaps Status Bar on Android when Layout Limits removed (#24694), similarity score: 0.74
- If Maui use Shell, in android ,control cannot be placed at the top with immersive statusbar (#19549), similarity score: 0.73
- Unable to put content under statusbar with Shell Navigation in Android (#13788), similarity score: 0.73
- [Android] Fullscreen not filling space when hiding Navigation. (#13685), similarity score: 0.73
Closed similar issues:
- Shell.NavBarHasShadow not working correctly on Android (#19458), similarity score: 0.73
Note: You can give me feedback by thumbs upping or thumbs downing this comment.
Thanks for the quick solution. @Redth
Hi @Redth, thanks for sharing this workaround. I'm on net8.0-android and I have the same issue.
When trying to apply the workaround suggested above, the app won't compile with the following error message: 0>styles.xml(2): Error APT2260 : style attribute 'android:attr/windowOptOutEdgeToEdgeEnforcement' not found.
Is the workaround net9.0-android only?
Thanks
Hi @Redth, thanks for sharing this workaround. I'm on net8.0-android and I have the same issue.
When trying to apply the workaround suggested above, the app won't compile with the following error message: 0>styles.xml(2): Error APT2260 : style attribute 'android:attr/windowOptOutEdgeToEdgeEnforcement' not found.
Is the workaround net9.0-android only?
Thanks
It's Android API 35 only, which is technically only supported in .NET 9, however in .NET 8 you could technically still try to target API 35 by adding this to your AndroidManifest.xml file:
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="35" />
This goes inside the <manifest /> element.
NOTE: This won't allow you to use new API's in your app that are Android 35+ only, but it should make the tooling recognize the new attribute you're trying to use in the style.
Thank you!
Thank you for the work-around @Redth.
I've noticed the following error in my code for MainActivity however, the app still compiles, builds and runs in both debug and release. Not sure why this isn't found. I am on .NET9 so thought this would be supported.
We can use https://github.com/dotnet/maui/issues/2342 to track improvements to Safe Area support in .NET MAUI.
For someone looking to fix the same issue as me that doesnt have a values-v35 folder yet and no styles file in there. Reminder that Visual studio doesnt set it as an AndroidResource by default if you add an xml file using New Item.
Hi @Redth, thanks for sharing this workaround. I'm on net8.0-android and I have the same issue. When trying to apply the workaround suggested above, the app won't compile with the following error message: 0>styles.xml(2): Error APT2260 : style attribute 'android:attr/windowOptOutEdgeToEdgeEnforcement' not found. Is the workaround net9.0-android only? Thanks
It's Android API 35 only, which is technically only supported in .NET 9, however in .NET 8 you could technically still try to target API 35 by adding this to your AndroidManifest.xml file:
This goes inside the ` ` element. NOTE: This won't allow you to use new API's in your app that are Android 35+ only, but it should make the tooling recognize the new attribute you're trying to use in the style.
Hi @Redth I have tried to add android:targetSdkVersion="35". It, with .NET8, compiles and I can produce an APK. When I go to install and run it on a device < 35, the app crashes with a log similar to this: Assertion at /__w/1/s/src/mono/mono/metadata/object.c:4410, condition is_ok (error)' not met, function:mono_unhandled_exception_internal, (null) assembly:System.Private.CoreLib.dll type:AggregateException member:(null) 12-04 11:30:15.543 15378 15415 F libc : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 15415 (Finalizer), pid 15378
Going back to android:targetSdkVersion="34", the app does not crash. Is it absolutely necessary to switch to .NET9 to use android:targetSdkVersion="35"?
I'm on .NET 9.0 and I get the following error:
'ResourceConstant.Style' does not contain a definition for 'OptOutEdgeToEdgeEnforcement'
Do need to do something special in the .csproj file to add these new style.xml resource/values?
I have added both styles.xml files in the paths explained above in the workaround. And I added those files as "New Item" per @Gekidoku instructions.
I'm on .NET 9.0 and I get the following error:
'ResourceConstant.Style' does not contain a definition for 'OptOutEdgeToEdgeEnforcement'Do need to do something special in the .csproj file to add these new style.xml resource/values?
I have added both styles.xml files in the paths explained above in the workaround. And I added those files as "New Item" per @Gekidoku instructions.
I had the same issue, you need to set the Build Action for the styles.xml files as AndroidResource.
See the images below if you are unsure how to do this
I'm on .NET 9.0 and I get the following error:
'ResourceConstant.Style' does not contain a definition for 'OptOutEdgeToEdgeEnforcement'Do need to do something special in the .csproj file to add these new style.xml resource/values? I have added both styles.xml files in the paths explained above in the workaround. And I added those files as "New Item" per @Gekidoku instructions.I had the same issue, you need to set the Build Action for the
styles.xmlfiles asAndroidResource. See the images below if you are unsure how to do this
Just logged in to reply with the same. In one project it automatically set the build action iirc. In another VS didnt.
These instructions may be outdated as edge-to-edge is opted out by default now as per PR#25517.
We were having trouble working out how to opt in since we use edge-to-edge in our App and finally found that PR which suggests we need to set <item name="maui_edgetoedge_optout">false</item>.
@Redth, that PR has documentation on what's happening; however, it never made it into the release notes or any official docs.