implement edge-to-edge

This commit is contained in:
adbenitez 2025-07-15 17:43:32 +02:00
parent 54f2d2e991
commit a9541a936e
33 changed files with 88 additions and 19 deletions

View file

@ -1,5 +1,5 @@
plugins { plugins {
id 'com.android.application' version '8.5.2' id 'com.android.application' version '8.11.1'
id 'com.google.gms.google-services' version '4.4.1' id 'com.google.gms.google-services' version '4.4.1'
} }
@ -15,7 +15,7 @@ repositories {
android { android {
namespace "org.thoughtcrime.securesms" namespace "org.thoughtcrime.securesms"
flavorDimensions "none" flavorDimensions "none"
compileSdk 34 compileSdk 35
// Set NDK version to strip native libraries. // Set NDK version to strip native libraries.
// Even though we compile our libraries outside Gradle with `scripts/ndk-make.sh`, // Even though we compile our libraries outside Gradle with `scripts/ndk-make.sh`,
@ -34,7 +34,7 @@ android {
multiDexEnabled true multiDexEnabled true
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 34 targetSdkVersion 35
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
@ -151,7 +151,7 @@ dependencies {
implementation 'androidx.sharetarget:sharetarget:1.2.0' implementation 'androidx.sharetarget:sharetarget:1.2.0'
implementation 'androidx.webkit:webkit:1.12.1' implementation 'androidx.webkit:webkit:1.12.1'
implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.appcompat:appcompat:1.7.0' implementation 'androidx.appcompat:appcompat:1.7.1'
implementation 'com.google.android.material:material:1.12.0' implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.legacy:legacy-support-v13:1.0.0' implementation 'androidx.legacy:legacy-support-v13:1.0.0'
implementation ('androidx.preference:preference:1.2.1') { implementation ('androidx.preference:preference:1.2.1') {

View file

@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d distributionSha256Sum=20f1b1176237254a6fc204d8434196fa11a4cfb387567519c61556e8710aed78
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000 networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View file

@ -73,11 +73,13 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
@Override @Override
protected void onCreate(Bundle icicle, boolean ready) { protected void onCreate(Bundle icicle, boolean ready) {
setContentView(R.layout.activity_application_preferences);
//noinspection ConstantConditions //noinspection ConstantConditions
this.getSupportActionBar().setDisplayHomeAsUpEnabled(true); this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (icicle == null) { if (icicle == null) {
initFragment(android.R.id.content, new ApplicationPreferenceFragment()); initFragment(R.id.fragment, new ApplicationPreferenceFragment());
} }
} }
@ -89,7 +91,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
showBackupProvider(); showBackupProvider();
return; return;
} }
Fragment fragment = getSupportFragmentManager().findFragmentById(android.R.id.content); Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment);
fragment.onActivityResult(requestCode, resultCode, data); fragment.onActivityResult(requestCode, resultCode, data);
} }
@ -262,7 +264,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(android.R.id.content, fragment); fragmentTransaction.replace(R.id.fragment, fragment);
fragmentTransaction.addToBackStack(null); fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit(); fragmentTransaction.commit();
} }

View file

@ -7,10 +7,12 @@ import android.view.MenuItem;
import android.view.ViewConfiguration; import android.view.ViewConfiguration;
import android.view.WindowManager; import android.view.WindowManager;
import androidx.activity.EdgeToEdge;
import androidx.annotation.IdRes; import androidx.annotation.IdRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.WindowCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import org.thoughtcrime.securesms.util.DynamicTheme; import org.thoughtcrime.securesms.util.DynamicTheme;
@ -31,7 +33,9 @@ public abstract class BaseActionBarActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
onPreCreate(); onPreCreate();
EdgeToEdge.enable(this); // docs says to use: WindowCompat.enableEdgeToEdge(getWindow()); but it is not available
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
WindowCompat.getInsetsController(getWindow(), getWindow().getDecorView()).setAppearanceLightStatusBars(false); // force white text in status bar
} }
@Override @Override

View file

@ -30,9 +30,10 @@ public class BlockedContactsActivity extends PassphraseRequiredActionBarActivity
@Override @Override
public void onCreate(Bundle bundle, boolean ready) { public void onCreate(Bundle bundle, boolean ready) {
setContentView(R.layout.activity_blocked_contacts);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(R.string.pref_blocked_contacts); getSupportActionBar().setTitle(R.string.pref_blocked_contacts);
initFragment(android.R.id.content, new BlockedAndShareContactsFragment(), getIntent().getExtras()); initFragment(R.id.fragment, new BlockedAndShareContactsFragment(), getIntent().getExtras());
} }
@Override @Override

View file

@ -866,8 +866,7 @@ public class ConversationFragment extends MessageSelectorFragment
Window window = getActivity().getWindow(); Window window = getActivity().getWindow();
statusBarColor = window.getStatusBarColor(); statusBarColor = window.getStatusBarColor();
window.setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar)); Util.setStatusBarColor(window, getResources().getColor(R.color.action_mode_status_bar));
Util.redMenuItem(menu, R.id.menu_context_delete_message); Util.redMenuItem(menu, R.id.menu_context_delete_message);
setCorrectMenuVisibility(menu); setCorrectMenuVisibility(menu);
ConversationAdaptiveActionsToolbar.adjustMenuActions(menu, 10, requireActivity().getWindow().getDecorView().getMeasuredWidth()); ConversationAdaptiveActionsToolbar.adjustMenuActions(menu, 10, requireActivity().getWindow().getDecorView().getMeasuredWidth());
@ -884,7 +883,7 @@ public class ConversationFragment extends MessageSelectorFragment
((ConversationAdapter)list.getAdapter()).clearSelection(); ((ConversationAdapter)list.getAdapter()).clearSelection();
list.getAdapter().notifyDataSetChanged(); list.getAdapter().notifyDataSetChanged();
getActivity().getWindow().setStatusBarColor(statusBarColor); Util.setStatusBarColor(getActivity().getWindow(), statusBarColor);
actionMode = null; actionMode = null;
hideAddReactionView(); hideAddReactionView();

View file

@ -21,6 +21,7 @@ public class ConversationListArchiveActivity extends PassphraseRequiredActionBar
{ {
@Override @Override
protected void onCreate(Bundle icicle, boolean ready) { protected void onCreate(Bundle icicle, boolean ready) {
setContentView(R.layout.activity_conversation_list_archive);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (isRelayingMessageContent(this)) { if (isRelayingMessageContent(this)) {
getSupportActionBar().setTitle(isSharing(this) ? R.string.chat_share_with_title : R.string.forward_to); getSupportActionBar().setTitle(isSharing(this) ? R.string.chat_share_with_title : R.string.forward_to);
@ -31,7 +32,7 @@ public class ConversationListArchiveActivity extends PassphraseRequiredActionBar
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putBoolean(ConversationListFragment.ARCHIVE, true); bundle.putBoolean(ConversationListFragment.ARCHIVE, true);
initFragment(android.R.id.content, new ConversationListFragment(), bundle); initFragment(R.id.fragment, new ConversationListFragment(), bundle);
} }
@Override @Override

View file

@ -73,11 +73,11 @@ public class BackupTransferActivity extends BaseActionBarActivity {
switch(transferMode) { switch(transferMode) {
case SENDER_SHOW_QR: case SENDER_SHOW_QR:
initFragment(android.R.id.content, new BackupProviderFragment(), icicle); initFragment(R.id.backup_provider_fragment, new BackupProviderFragment(), icicle);
break; break;
case RECEIVER_SCAN_QR: case RECEIVER_SCAN_QR:
initFragment(android.R.id.content, new BackupReceiverFragment(), icicle); initFragment(R.id.backup_provider_fragment, new BackupReceiverFragment(), icicle);
break; break;
} }

View file

@ -23,9 +23,11 @@ import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.text.Spannable; import android.text.Spannable;
@ -36,6 +38,8 @@ import android.text.style.StyleSpan;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.Window;
import android.view.WindowInsets;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -111,6 +115,23 @@ public class Util {
} }
} }
public static void setStatusBarColor(Window window, int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
// Android 15+
window.getDecorView().setOnApplyWindowInsetsListener((view, insets) -> {
Insets statusBarInsets = insets.getInsets(WindowInsets.Type.statusBars());
view.setBackgroundColor(color);
// Adjust padding to avoid overlap
//view.setPadding(0, statusBarInsets.top, 0, 0);
return insets;
});
} else {
// Android 14 and below
window.setStatusBarColor(color);
}
}
public static @NonNull int[] appendInt(@Nullable int[] cur, int val) { public static @NonNull int[] appendInt(@Nullable int[] cur, int val) {
if (cur == null) { if (cur == null) {
return new int[] { val }; return new int[] { val };

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:id="@+id/fragment" />

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:id="@+id/fragment" />

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:id="@+id/fragment" />

View file

@ -3,6 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_width="match_parent" android:layout_width="match_parent"
android:fitsSystemWindows="true"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout

View file

@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical" android:orientation="vertical"
android:gravity="center_horizontal" android:gravity="center_horizontal"
tools:context=".WelcomeActivity"> tools:context=".WelcomeActivity">

View file

@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical" android:orientation="vertical"
android:gravity="center_horizontal" android:gravity="center_horizontal"
tools:context=".WelcomeActivity"> tools:context=".WelcomeActivity">

View file

@ -2,6 +2,7 @@
<FrameLayout <FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_container" android:id="@+id/layout_container"
android:fitsSystemWindows="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">

View file

@ -3,6 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_width="match_parent" android:layout_width="match_parent"
android:fitsSystemWindows="true"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout

View file

@ -2,4 +2,5 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:id="@+id/backup_provider_fragment" /> android:id="@+id/backup_provider_fragment" />

View file

@ -2,6 +2,7 @@
<LinearLayout android:layout_gravity="center" <LinearLayout android:layout_gravity="center"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:fitsSystemWindows="true"
android:orientation="vertical" android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">

View file

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true"
android:layout_height="match_parent" android:layout_width="match_parent"> android:layout_height="match_parent" android:layout_width="match_parent">
<org.thoughtcrime.securesms.components.ScaleStableImageView <org.thoughtcrime.securesms.components.ScaleStableImageView

View file

@ -4,6 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@id/container" android:id="@id/container"
android:orientation="vertical" android:orientation="vertical"
android:fitsSystemWindows="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">

View file

@ -3,6 +3,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout <LinearLayout

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:layout_width="match_parent" <FrameLayout android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true"
xmlns:android="http://schemas.android.com/apk/res/android"> xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout <LinearLayout

View file

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container" android:id="@+id/fragment_container"
android:orientation="vertical" android:orientation="vertical"
android:fitsSystemWindows="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">

View file

@ -4,6 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:fillViewport="true" android:fillViewport="true"
tools:context=".contacts.NewContactActivity"> tools:context=".contacts.NewContactActivity">

View file

@ -3,6 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_width="match_parent" android:layout_width="match_parent"
android:fitsSystemWindows="true"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout

View file

@ -2,6 +2,7 @@
<FrameLayout <FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:fitsSystemWindows="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">

View file

@ -4,6 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:orientation="vertical" android:orientation="vertical"
tools:context=".proxy.ProxySettingsActivity"> tools:context=".proxy.ProxySettingsActivity">

View file

@ -4,6 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:fillViewport="true" android:fillViewport="true"
tools:context=".RegistrationActivity"> tools:context=".RegistrationActivity">

View file

@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical"> android:orientation="vertical">
<com.google.android.material.tabs.TabLayout <com.google.android.material.tabs.TabLayout

View file

@ -3,6 +3,7 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:wheel="http://schemas.android.com/apk/res-auto" xmlns:wheel="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:orientation="vertical"
android:fitsSystemWindows="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">

View file

@ -3,6 +3,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical"> android:orientation="vertical">
<WebView android:id="@+id/webview" <WebView android:id="@+id/webview"

View file

@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical" android:orientation="vertical"
android:gravity="center_horizontal" android:gravity="center_horizontal"
tools:context=".WelcomeActivity"> tools:context=".WelcomeActivity">