mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
NewContactActivity: properly implement edge-to-edge
This commit is contained in:
@@ -4,6 +4,7 @@ import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.WindowManager;
|
||||
|
||||
@@ -11,12 +12,14 @@ import androidx.activity.EdgeToEdge;
|
||||
import androidx.annotation.IdRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.Prefs;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
@@ -33,11 +36,28 @@ public abstract class BaseActionBarActivity extends AppCompatActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
onPreCreate();
|
||||
EdgeToEdge.enable(this); // docs says to use: WindowCompat.enableEdgeToEdge(getWindow()); but it is not available
|
||||
EdgeToEdge.enable(this); // TODO: docs says to use: WindowCompat.enableEdgeToEdge(getWindow()); but it requires dep androidx.core:core:1.17.0 which in turns requires to target SDK 36
|
||||
super.onCreate(savedInstanceState);
|
||||
WindowCompat.getInsetsController(getWindow(), getWindow().getDecorView()).setAppearanceLightStatusBars(false); // force white text in status bar
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
|
||||
// For activities without a custom toolbar, apply insets to status_bar_background view
|
||||
View statusBarBackground = findViewById(R.id.status_bar_background);
|
||||
if (statusBarBackground != null) {
|
||||
ViewUtil.applyWindowInsetsAsHeight(statusBarBackground);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
// elevation is set via status_bar_background view
|
||||
// otherwise there is a drop-shadow at the top
|
||||
actionBar.setElevation(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
@@ -42,9 +42,10 @@ public class NewContactActivity extends PassphraseRequiredActionBarActivity
|
||||
actionBar.setTitle(R.string.menu_new_classic_contact);
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
actionBar.setHomeAsUpIndicator(R.drawable.ic_close_white_24dp);
|
||||
actionBar.setElevation(0); // TODO: use custom toolbar instead
|
||||
}
|
||||
|
||||
ViewUtil.applyWindowInsets(findViewById(R.id.content_container));
|
||||
|
||||
nameInput = ViewUtil.findById(this, R.id.name_text);
|
||||
addrInput = ViewUtil.findById(this, R.id.email_text);
|
||||
addrInput.setText(getIntent().getStringExtra(ADDR_EXTRA));
|
||||
|
||||
@@ -41,10 +41,12 @@ import androidx.annotation.IdRes;
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.views.Stub;
|
||||
|
||||
import chat.delta.util.ListenableFuture;
|
||||
@@ -294,4 +296,91 @@ public class ViewUtil {
|
||||
}
|
||||
return selection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply window insets to a view by adding padding to avoid drawing elements behind system bars.
|
||||
* Convenience method that applies insets to all sides.
|
||||
*
|
||||
* @param view The view to apply insets to
|
||||
*/
|
||||
public static void applyWindowInsets(@NonNull View view) {
|
||||
applyWindowInsets(view, true, true, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply window insets to a view by adding padding to avoid drawing elements behind system bars.
|
||||
*
|
||||
* This method stores the original padding values in view tags to ensure that
|
||||
* padding doesn't accumulate on multiple inset applications.
|
||||
*
|
||||
* @param view The view to apply insets to
|
||||
* @param left Whether to apply left inset
|
||||
* @param top Whether to apply top inset
|
||||
* @param right Whether to apply right inset
|
||||
* @param bottom Whether to apply bottom inset
|
||||
*/
|
||||
public static void applyWindowInsets(@NonNull View view, boolean left, boolean top, boolean right, boolean bottom) {
|
||||
// Store the original padding as a tag only if not already stored
|
||||
// This prevents losing the true original padding on subsequent calls
|
||||
if (view.getTag(R.id.tag_window_insets_padding_left) == null) {
|
||||
view.setTag(R.id.tag_window_insets_padding_left, view.getPaddingLeft());
|
||||
view.setTag(R.id.tag_window_insets_padding_top, view.getPaddingTop());
|
||||
view.setTag(R.id.tag_window_insets_padding_right, view.getPaddingRight());
|
||||
view.setTag(R.id.tag_window_insets_padding_bottom, view.getPaddingBottom());
|
||||
}
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> {
|
||||
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||
|
||||
// Retrieve the original padding values from tags with null checks
|
||||
Integer leftTag = (Integer) v.getTag(R.id.tag_window_insets_padding_left);
|
||||
Integer topTag = (Integer) v.getTag(R.id.tag_window_insets_padding_top);
|
||||
Integer rightTag = (Integer) v.getTag(R.id.tag_window_insets_padding_right);
|
||||
Integer bottomTag = (Integer) v.getTag(R.id.tag_window_insets_padding_bottom);
|
||||
int basePaddingLeft = leftTag != null ? leftTag : 0;
|
||||
int basePaddingTop = topTag != null ? topTag : 0;
|
||||
int basePaddingRight = rightTag != null ? rightTag : 0;
|
||||
int basePaddingBottom = bottomTag != null ? bottomTag : 0;
|
||||
|
||||
v.setPadding(
|
||||
left ? basePaddingLeft + insets.left : basePaddingLeft,
|
||||
top ? basePaddingTop + insets.top : basePaddingTop,
|
||||
right ? basePaddingRight + insets.right : basePaddingRight,
|
||||
bottom ? basePaddingBottom + insets.bottom : basePaddingBottom
|
||||
);
|
||||
|
||||
return windowInsets;
|
||||
});
|
||||
|
||||
// Request the initial insets to be dispatched if the view is attached
|
||||
if (view.isAttachedToWindow()) {
|
||||
ViewCompat.requestApplyInsets(view);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the top status bar inset as the height of a view.
|
||||
* This is useful for creating a colored status bar background view.
|
||||
*
|
||||
* @param view The view whose height should be set to the status bar inset
|
||||
*/
|
||||
public static void applyWindowInsetsAsHeight(@NonNull View view) {
|
||||
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> {
|
||||
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||
|
||||
android.view.ViewGroup.LayoutParams params = v.getLayoutParams();
|
||||
if (params != null) {
|
||||
params.height = insets.top;
|
||||
v.setLayoutParams(params);
|
||||
}
|
||||
|
||||
return windowInsets;
|
||||
});
|
||||
|
||||
// Request the initial insets to be dispatched if the view is attached
|
||||
if (view.isAttachedToWindow()) {
|
||||
ViewCompat.requestApplyInsets(view);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user