android: Fix edge-to-edge layout issues with settings and app selection

Using FrameLayout for the settings instead of the recommended
FragmentContainerView because the latter makes handling insets more
complicated (fitsSystemWindows doesn't work as the fragment is responsible
for handling insets but how that should work with PreferenceFragmentCompat
is unclear).

Fixes: 2404b2bee6 ("android: Apply UI changes for edge-to-edge views in Android 15+")
This commit is contained in:
Tobias Brunner
2025-10-30 16:55:05 +01:00
parent 3741d24a25
commit a4f32a5a46
7 changed files with 62 additions and 8 deletions
@@ -20,7 +20,9 @@ import android.content.Intent;
import android.os.Bundle;
import android.view.MenuItem;
import org.strongswan.android.R;
import org.strongswan.android.data.VpnProfileDataSource;
import org.strongswan.android.utils.Utils;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.Nullable;
@@ -38,8 +40,9 @@ public class SelectedApplicationsActivity extends AppCompatActivity
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.selected_applications_activity);
WindowCompat.enableEdgeToEdge(getWindow());
WindowCompat.setDecorFitsSystemWindows(getWindow(), true);
Utils.applyWindowInsetsAsMarginsForLists(findViewById(R.id.fragment_container));
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
@@ -59,7 +62,7 @@ public class SelectedApplicationsActivity extends AppCompatActivity
if (mApps == null)
{
mApps = new SelectedApplicationsListFragment();
fm.beginTransaction().add(android.R.id.content, mApps, LIST_TAG).commit();
fm.beginTransaction().add(R.id.fragment_container, mApps, LIST_TAG).commit();
}
}
@@ -34,6 +34,7 @@ import org.strongswan.android.R;
import org.strongswan.android.data.VpnProfileDataSource;
import org.strongswan.android.ui.adapter.SelectedApplicationEntry;
import org.strongswan.android.ui.adapter.SelectedApplicationsAdapter;
import org.strongswan.android.utils.Utils;
import java.util.ArrayList;
import java.util.Collections;
@@ -61,6 +62,9 @@ public class SelectedApplicationsListFragment extends ListFragment implements Me
super.onViewCreated(view, savedInstanceState);
requireActivity().addMenuProvider(this, getViewLifecycleOwner());
getListView().setClipToPadding(false);
Utils.applyWindowInsetsAsPaddingForLists(getListView());
final boolean readOnly = getActivity().getIntent().getBooleanExtra(VpnProfileDataSource.KEY_READ_ONLY, false);
getListView().setChoiceMode(readOnly ? ListView.CHOICE_MODE_NONE : ListView.CHOICE_MODE_MULTIPLE);
@@ -19,6 +19,8 @@ package org.strongswan.android.ui;
import android.os.Bundle;
import android.view.MenuItem;
import org.strongswan.android.R;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.WindowCompat;
@@ -29,14 +31,18 @@ public class SettingsActivity extends AppCompatActivity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_activity);
WindowCompat.enableEdgeToEdge(getWindow());
WindowCompat.setDecorFitsSystemWindows(getWindow(), true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment())
.commit();
if (savedInstanceState == null)
{
getSupportFragmentManager().beginTransaction()
.setReorderingAllowed(true)
.add(R.id.fragment_container, SettingsFragment.class, null)
.commit();
}
}
@Override
@@ -41,7 +41,6 @@ import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDialogFragment;
import androidx.core.view.WindowCompat;
import androidx.fragment.app.FragmentTransaction;
public class TrustedCertificateImportActivity extends AppCompatActivity
@@ -33,7 +33,6 @@ import org.strongswan.android.logic.TrustedCertificateManager;
import org.strongswan.android.logic.TrustedCertificateManager.TrustedCertificateSource;
import org.strongswan.android.security.TrustedCertificateEntry;
import org.strongswan.android.ui.CertificateDeleteConfirmationDialog.OnCertificateDeleteListener;
import org.strongswan.android.utils.Utils;
import java.security.KeyStore;
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2025 Tobias Brunner
Copyright (C) secunet Security Networks AG
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
-->
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2025 Tobias Brunner
Copyright (C) secunet Security Networks AG
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true" />