|
2 | 2 |
|
3 | 3 | import android.app.Activity; |
4 | 4 | import android.app.Dialog; |
5 | | -import android.content.Context; |
6 | 5 | import android.content.DialogInterface; |
7 | 6 | import android.graphics.Color; |
8 | | -import android.graphics.Point; |
9 | 7 | import android.graphics.Rect; |
10 | 8 | import android.graphics.drawable.ColorDrawable; |
11 | 9 | import android.graphics.drawable.Drawable; |
|
16 | 14 | import android.os.Bundle; |
17 | 15 | import android.os.Handler; |
18 | 16 | import android.os.Looper; |
19 | | -import android.util.DisplayMetrics; |
20 | | -import android.view.Display; |
21 | 17 | import android.view.Gravity; |
22 | 18 | import android.view.LayoutInflater; |
23 | 19 | import android.view.OrientationEventListener; |
|
35 | 31 | import androidx.core.graphics.ColorUtils; |
36 | 32 | import androidx.core.graphics.Insets; |
37 | 33 | import androidx.core.view.ViewCompat; |
| 34 | +import androidx.core.view.WindowCompat; |
38 | 35 | import androidx.core.view.WindowInsetsCompat; |
39 | 36 | import androidx.fragment.app.DialogFragment; |
40 | 37 |
|
@@ -78,6 +75,7 @@ public class IterableInAppFragmentHTMLNotification extends DialogFragment implem |
78 | 75 | private boolean shouldAnimate; |
79 | 76 | private double inAppBackgroundAlpha; |
80 | 77 | private String inAppBackgroundColor; |
| 78 | + private boolean hostIsEdgeToEdge; |
81 | 79 |
|
82 | 80 | public static IterableInAppFragmentHTMLNotification createInstance(@NonNull String htmlString, boolean callbackOnCancel, @NonNull IterableHelper.IterableUrlCallback clickCallback, @NonNull IterableInAppLocation location, @NonNull String messageId, @NonNull Double backgroundAlpha, @NonNull Rect padding) { |
83 | 81 | return IterableInAppFragmentHTMLNotification.createInstance(htmlString, callbackOnCancel, clickCallback, location, messageId, backgroundAlpha, padding, false, new IterableInAppMessage.InAppBgColor(null, 0.0f)); |
@@ -176,11 +174,8 @@ public void onCancel(DialogInterface dialog) { |
176 | 174 | applyWindowGravity(dialog.getWindow(), "onCreateDialog"); |
177 | 175 | } |
178 | 176 |
|
179 | | - if (getInAppLayout(insetPadding) != InAppLayout.FULLSCREEN && getInAppLayout(insetPadding) != InAppLayout.TOP) { |
180 | | - // For TOP layout in-app, status bar will be opaque so that the in-app content does not overlap with translucent status bar. |
181 | | - // For other non-fullscreen in-apps layouts (BOTTOM and CENTER), status bar will be translucent |
182 | | - dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); |
183 | | - } |
| 177 | + hostIsEdgeToEdge = isHostActivityEdgeToEdge(); |
| 178 | + configureSystemBarBehavior(dialog.getWindow()); |
184 | 179 | return dialog; |
185 | 180 | } |
186 | 181 |
|
@@ -289,9 +284,7 @@ public void run() { |
289 | 284 | @Override |
290 | 285 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { |
291 | 286 | super.onViewCreated(view, savedInstanceState); |
292 | | - // Handle edge-to-edge insets with modern approach (only for non-fullscreen) |
293 | | - // Full screen in-apps should not have padding from system bars |
294 | | - if (getInAppLayout(insetPadding) != InAppLayout.FULLSCREEN) { |
| 287 | + if (getInAppLayout(insetPadding) != InAppLayout.FULLSCREEN && hostIsEdgeToEdge) { |
295 | 288 | ViewCompat.setOnApplyWindowInsetsListener(view, (v, insets) -> { |
296 | 289 | Insets sysBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); |
297 | 290 | v.setPadding(0, sysBars.top, 0, sysBars.bottom); |
@@ -594,29 +587,11 @@ public void run() { |
594 | 587 | return; |
595 | 588 | } |
596 | 589 |
|
597 | | - DisplayMetrics displayMetrics = activity.getResources().getDisplayMetrics(); |
598 | 590 | Window window = notification.getDialog().getWindow(); |
599 | 591 | Rect insetPadding = notification.insetPadding; |
600 | 592 |
|
601 | | - WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); |
602 | | - Display display = wm.getDefaultDisplay(); |
603 | | - Point size = new Point(); |
604 | | - |
605 | | - // Get the correct screen size based on api level |
606 | | - // https://stackoverflow.com/questions/35780980/getting-the-actual-screen-height-android |
607 | | - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { |
608 | | - display.getRealSize(size); |
609 | | - } else { |
610 | | - display.getSize(size); |
611 | | - } |
612 | | - |
613 | | - int webViewWidth = size.x; |
614 | | - int webViewHeight = size.y; |
615 | | - |
616 | | - //Check if the dialog is full screen |
617 | 593 | if (insetPadding.bottom == 0 && insetPadding.top == 0) { |
618 | | - //Handle full screen |
619 | | - window.setLayout(webViewWidth, webViewHeight); |
| 594 | + window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); |
620 | 595 | } else { |
621 | 596 | // Resize the WebView directly with explicit size |
622 | 597 | float relativeHeight = height * getResources().getDisplayMetrics().density; |
@@ -703,6 +678,56 @@ static int roundToNearest90Degrees(int orientation) { |
703 | 678 | } |
704 | 679 | } |
705 | 680 |
|
| 681 | + private void configureSystemBarBehavior(Window window) { |
| 682 | + if (window == null) return; |
| 683 | + Activity activity = getActivity(); |
| 684 | + if (activity == null || activity.getWindow() == null) return; |
| 685 | + |
| 686 | + if (hostIsEdgeToEdge) { |
| 687 | + WindowCompat.setDecorFitsSystemWindows(window, false); |
| 688 | + window.setStatusBarColor(Color.TRANSPARENT); |
| 689 | + window.setNavigationBarColor(Color.TRANSPARENT); |
| 690 | + } else { |
| 691 | + window.setStatusBarColor(activity.getWindow().getStatusBarColor()); |
| 692 | + window.setNavigationBarColor(activity.getWindow().getNavigationBarColor()); |
| 693 | + } |
| 694 | + } |
| 695 | + |
| 696 | + private boolean isHostActivityEdgeToEdge() { |
| 697 | + Activity activity = getActivity(); |
| 698 | + if (activity == null || activity.getWindow() == null) return false; |
| 699 | + |
| 700 | + if (hasEdgeToEdgeLegacyFlags(activity)) { |
| 701 | + return true; |
| 702 | + } |
| 703 | + |
| 704 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { |
| 705 | + return isContentDrawnBehindSystemBars(activity); |
| 706 | + } |
| 707 | + |
| 708 | + return false; |
| 709 | + } |
| 710 | + |
| 711 | + private boolean hasEdgeToEdgeLegacyFlags(Activity activity) { |
| 712 | + int flags = activity.getWindow().getDecorView().getSystemUiVisibility(); |
| 713 | + return (flags & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0; |
| 714 | + } |
| 715 | + |
| 716 | + private boolean isContentDrawnBehindSystemBars(Activity activity) { |
| 717 | + View contentView = activity.findViewById(android.R.id.content); |
| 718 | + if (contentView == null) return false; |
| 719 | + |
| 720 | + int contentTop = getViewTopPositionInWindow(contentView); |
| 721 | + boolean statusBarPushesContentDown = contentTop > 0; |
| 722 | + return !statusBarPushesContentDown; |
| 723 | + } |
| 724 | + |
| 725 | + private int getViewTopPositionInWindow(View view) { |
| 726 | + int[] position = new int[2]; |
| 727 | + view.getLocationInWindow(position); |
| 728 | + return position[1]; |
| 729 | + } |
| 730 | + |
706 | 731 | /** |
707 | 732 | * Sets the window gravity based on inset padding |
708 | 733 | * |
|
0 commit comments