Problem with the new Edge-to-Edge requirement in Android 15 when using net9.0-android35

Graham McKechnie 421 Reputation points
2024-11-18T02:42:04.89+00:00

Before modifying my app to support edge-to-edge, I thought I’d first try with one of my sample apps on my GitHub page. The existing sample app didn’t have a fragment with a RecyclerView, so I added a new fragment containing a RecyclerView to test the edge-to-edge requirements on the new fragment.

The new Android 15 requirements for a RecyclerView are the following

  1. The last RecyclerView item should be visible above the NavigationBar.
  2. Items of the RecyclerView should be visible in the NavigationBar while scrolling.
  3. android:clipToPadding="false" should be included in the xml layout of the recyclerview.

Before Android 15, you would typically have to use an OnApplyWindowInsetsListener to provide inserts of type WindowInsetsCompat.Type.NavigationBars() for the RecyclerView.

It would look like the following:

public WindowInsetsCompat OnApplyWindowInsets(View v, WindowInsetsCompat insets)

{

    if (v is RecyclerView)

    {

         AndroidX.Core.Graphics.Insets navigationBarInsets = insets.GetInsets(WindowInsetsCompat.Type.NavigationBars());

        v.SetPadding(v.Left, v.Top, v.Right, navigationBarInsets.Bottom + initialPaddingBottom);

        return insets;

    }

}

This does, in fact, achieve the above three requirements, and if you were only concerned with 3-button navigation, you would be done. However, once you change to Gesture navigation, you soon realise that you get weird behaviour when attempting to close the fragment. First, you can’t back out of a left or right-back gesture to close the fragment. Second, the RecyclerView disappears but leaves the header of the RecyclerView behind, necessitating a second swipe to close the fragment.

To get around the problem, I had to develop a new function to determine whether the user uses Gesture navigation. e.g. IsGestureNavigation(WindowInsetsCompat insets). This does fix the problem.

So, the OnApplyWindowInsets listener above now is the following

AndroidX.Core.Graphics.Insets systemBarInsets = insets.GetInsets(WindowInsetsCompat.Type.SystemBars());

if (IsGestureNavigation(insets))

    v.SetPadding(systemBarInsets.Left, v.Top, systemBarInsets.Right, systemBarInsets.Bottom + initialPaddingBottom);

else

    v.SetPadding(v.Left, v.Top, v.Right, systemBarInsets.Bottom + initialPaddingBottom);

As I did, you may think this could be avoided by using a different combination of window inserts, for example, with WindowInsetsCompat.Type.SystemBars() | WindowInsetsCompat.Type.MandatorySystemGestures() or even WindowInsetsCompat.Type.SystemBars() | WindowInsetsCompat.Type. SystemGestures()

Either of the above can work for, say, Gesture navigation but then screws up 3-button navigation with unwanted padding.

So, it appears we have no choice but to use the new function.

My problem is that I do not know how robust this new IsGestureNavigation() is. It certainly works on all my test phones/tablets, but I would have thought that it shouldn’t be necessary as some combination of the standard WindowInsetsCompat.Type.?? would have been capable of handling it without the need for the Navigation mode test.

Please note that you don’t necessarily need an Android 15 device for this test, as any device using Android 10 and Android 15 supports Gesture Navigation. To make it easier to see the differences between edge-to-edge and not edge-to-edge for Android 10-14 devices,  I’ve included a preference setting that can be checked/unchecked. The preference isn’t enabled for an Android 15 device, which already defaults to edge-to-edge.

What I’m hoping for is Community support via feedback. If as many of you as possible could check this sample app on as many different phones/tablets as possible and inform me by email whether it works in all cases, we can all safely use this workaround function going forward. 

A couple of conditions.

If you already use the preview version of VS 2022, you need to upgrade it to VS 2002 17.13.0 Preview 1.0. Alternatively, you must upgrade your VS 2022 to 17.12.0, released on 15th Nov, along with the general release of .NET9. These are the only two VS 2022 versions supporting <TargetFramework>net9.0-android35</TargetFramework>. I haven’t tested VS Code yet, but I believe that it can also be upgraded to .NET9

The problem has been reported on https://github.com/dotnet/android/issues/9505. However, as it is unlikely to be a problem with any of the .NET for Android bindings, we can’t expect a solution from the Android team unless one of the developers there has a particular interest.

There is also a similar issue with Maui https://github.com/dotnet/maui/issues/24742. However, their solution is to opt out of going edge-to-edge for Android 15, which obviously isn’t a solution.

The project is at https://github.com/gmck/NavigationGraph9Net9.

After you have updated VS 2002, the easiest way to obtain the project is to clone the project. Click on the link above, and GitHub will load the repo. If you are unfamiliar with GitHub, you’ll notice a Code button at the top of the repo. When you click that button, you will see a URL for the project.

Click the copy button and then open VS 2022. On the first screen, under the heading Get Started, choose Clone a repository. When the next window opens, paste the URL into the field Repository Location and then select a folder of your choice or just accept the default path. At the bottom of the dialog, click the Clone button, and you are done. Visual Studio will load the project, just like any of your projects. Build, deploy and run the app.

Open the Books fragment from the NavigationView menu, rotate the device in either direction observing the RecyclerView for correct padding and then repeat changing to either 3-button or gesture navigation. While in Gesture mode, close the fragment using a back gesture from either the left or right sides.

My email address is available on the main page of the repo. Note that you must be signed into GitHub to see a repo owner's email address. I’m just asking for responses as to whether the RecyclerView works as expected on your devices. A reply with something as simple as Phone name, Android Version, works/not works would be fine, but if you wish to ask questions, please do so. I don’t think it would be appropriate to receive your answers here, hence the email request. I’ll report back here once I have a reasonable collection of answers.

Obviously, going edge-to-edge is a little bit more complex than getting the correct behaviour of a RecyclerView, so this project takes you through the process of what is required. The Readme describes the complete process, and the code has plenty of comments. There is also a companion project, NavigationGraph8Net8, which is what the original NavigationGraph9Net9 started as, which makes it relatively easy to track the changes from moving from NET8 using Android 14 to NET9 and Android 15 and supporting edge-to-edge. I recently updated the BooksFragment code in the NET8 project just to confirm if the RecylcerView operated correctly without the new function.

The Readme also contains various links regarding going edge-to-edge, including both Google documentation and articles discussing edge-to-edge requirements.

I’ll also post this on StackOverFlow (xamarin.android), hoping to maximise the responses.

Thanks for your help.

.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,714 questions
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.