-
Notifications
You must be signed in to change notification settings - Fork 33
MOB-11663-InApp-Calculations #949
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
0fb31c1
723c6c9
8e15c0a
e85d78a
0ba3d48
a1e5ab9
863f281
598a159
3e4dcd1
38bfdfc
04852ae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,7 @@ | |
| import android.view.WindowManager; | ||
| import android.view.animation.Animation; | ||
| import android.view.animation.AnimationUtils; | ||
| import android.widget.FrameLayout; | ||
| import android.widget.RelativeLayout; | ||
|
|
||
| import androidx.annotation.NonNull; | ||
|
|
@@ -58,6 +59,12 @@ | |
| private boolean callbackOnCancel = false; | ||
| private String htmlString; | ||
| private String messageId; | ||
|
|
||
| // Resize debouncing fields | ||
| private Handler resizeHandler = new Handler(); | ||
| private Runnable pendingResizeRunnable; | ||
| private float lastContentHeight = -1; | ||
| private static final int RESIZE_DEBOUNCE_DELAY_MS = 200; | ||
|
|
||
| private double backgroundAlpha; //TODO: remove in a future version | ||
| private Rect insetPadding; | ||
|
|
@@ -105,6 +112,35 @@ | |
| insetPadding = new Rect(); | ||
| this.setStyle(DialogFragment.STYLE_NO_FRAME, androidx.appcompat.R.style.Theme_AppCompat_NoActionBar); | ||
| } | ||
|
|
||
| @Override | ||
| public void onStart() { | ||
| super.onStart(); | ||
|
|
||
| // Set dialog positioning after the dialog is created and shown | ||
| Dialog dialog = getDialog(); | ||
| if (dialog != null) { | ||
| Window window = dialog.getWindow(); | ||
| if (window != null) { | ||
| WindowManager.LayoutParams windowParams = window.getAttributes(); | ||
| int startGravity = getVerticalLocation(insetPadding); | ||
|
|
||
| if (startGravity == Gravity.CENTER_VERTICAL) { | ||
| windowParams.gravity = Gravity.CENTER; | ||
| IterableLogger.d(TAG, "Set dialog gravity to CENTER in onStart"); | ||
| } else if (startGravity == Gravity.TOP) { | ||
| windowParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; | ||
| IterableLogger.d(TAG, "Set dialog gravity to TOP in onStart"); | ||
| } else if (startGravity == Gravity.BOTTOM) { | ||
| windowParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; | ||
| IterableLogger.d(TAG, "Set dialog gravity to BOTTOM in onStart"); | ||
| } | ||
|
|
||
| window.setAttributes(windowParams); | ||
| IterableLogger.d(TAG, "Applied window gravity in onStart: " + windowParams.gravity); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public void onCreate(@Nullable Bundle savedInstanceState) { | ||
|
|
@@ -144,6 +180,25 @@ | |
| } | ||
| }); | ||
| dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); | ||
|
|
||
| // Set window gravity for the dialog | ||
| Window window = dialog.getWindow(); | ||
| WindowManager.LayoutParams windowParams = window.getAttributes(); | ||
| int dialogGravity = getVerticalLocation(insetPadding); | ||
|
|
||
| if (dialogGravity == Gravity.CENTER_VERTICAL) { | ||
| windowParams.gravity = Gravity.CENTER; | ||
| IterableLogger.d(TAG, "Set dialog gravity to CENTER in onCreateDialog"); | ||
| } else if (dialogGravity == Gravity.TOP) { | ||
| windowParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; | ||
| IterableLogger.d(TAG, "Set dialog gravity to TOP in onCreateDialog"); | ||
| } else if (dialogGravity == Gravity.BOTTOM) { | ||
| windowParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; | ||
| IterableLogger.d(TAG, "Set dialog gravity to BOTTOM in onCreateDialog"); | ||
| } | ||
|
|
||
| window.setAttributes(windowParams); | ||
|
|
||
| if (getInAppLayout(insetPadding) == InAppLayout.FULLSCREEN) { | ||
| dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); | ||
| } else if (getInAppLayout(insetPadding) != InAppLayout.TOP) { | ||
|
|
@@ -162,41 +217,111 @@ | |
| if (getInAppLayout(insetPadding) == InAppLayout.FULLSCREEN) { | ||
| getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); | ||
| } | ||
|
|
||
| // Set initial window gravity based on inset padding | ||
| Window window = getDialog().getWindow(); | ||
| WindowManager.LayoutParams windowParams = window.getAttributes(); | ||
| int windowGravity = getVerticalLocation(insetPadding); | ||
|
|
||
| if (windowGravity == Gravity.CENTER_VERTICAL) { | ||
| windowParams.gravity = Gravity.CENTER; | ||
| IterableLogger.d(TAG, "Set initial CENTER window gravity in onCreateView"); | ||
| } else if (windowGravity == Gravity.TOP) { | ||
| windowParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; | ||
| IterableLogger.d(TAG, "Set initial TOP window gravity in onCreateView"); | ||
| } else if (windowGravity == Gravity.BOTTOM) { | ||
| windowParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; | ||
| IterableLogger.d(TAG, "Set initial BOTTOM window gravity in onCreateView"); | ||
| } | ||
|
|
||
| window.setAttributes(windowParams); | ||
|
|
||
| webView = new IterableWebView(getContext()); | ||
| webView.setId(R.id.webView); | ||
|
|
||
| // Debug the HTML content | ||
| IterableLogger.d(TAG, "HTML content preview: " + (htmlString.length() > 200 ? htmlString.substring(0, 200) + "..." : htmlString)); | ||
Ayyanchira marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| webView.createWithHtml(this, htmlString); | ||
|
|
||
| if (orientationListener == null) { | ||
| orientationListener = new OrientationEventListener(getContext(), SensorManager.SENSOR_DELAY_NORMAL) { | ||
| private int lastOrientation = -1; | ||
|
|
||
| // Resize the webView on device rotation | ||
| public void onOrientationChanged(int orientation) { | ||
| if (loaded) { | ||
| final Handler handler = new Handler(); | ||
| handler.postDelayed(new Runnable() { | ||
| @Override | ||
| public void run() { | ||
| runResizeScript(); | ||
| } | ||
| }, 1000); | ||
| if (loaded && webView != null) { | ||
| // Only trigger on significant orientation changes (90 degree increments) | ||
| int currentOrientation = ((orientation + 45) / 90) * 90; | ||
|
||
| if (currentOrientation != lastOrientation && lastOrientation != -1) { | ||
| lastOrientation = currentOrientation; | ||
|
|
||
| // Use longer delay for orientation changes to allow layout to stabilize | ||
| final Handler handler = new Handler(); | ||
|
||
| handler.postDelayed(new Runnable() { | ||
| @Override | ||
| public void run() { | ||
| IterableLogger.d(TAG, "Orientation changed, triggering resize"); | ||
| runResizeScript(); | ||
| } | ||
| }, 1500); // Increased delay for better stability | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Magic number |
||
| } else if (lastOrientation == -1) { | ||
| lastOrientation = currentOrientation; | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| } | ||
|
|
||
| orientationListener.enable(); | ||
|
|
||
| RelativeLayout relativeLayout = new RelativeLayout(this.getContext()); | ||
| RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT); | ||
| relativeLayout.setVerticalGravity(getVerticalLocation(insetPadding)); | ||
| relativeLayout.addView(webView, layoutParams); | ||
| // Create a FrameLayout as the main container for better positioning control | ||
| FrameLayout frameLayout = new FrameLayout(this.getContext()); | ||
Ayyanchira marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // Create a RelativeLayout as a wrapper for the WebView | ||
| RelativeLayout webViewContainer = new RelativeLayout(this.getContext()); | ||
|
|
||
| int gravity = getVerticalLocation(insetPadding); | ||
| IterableLogger.d(TAG, "Initial setup - gravity: " + gravity + " for inset padding: " + insetPadding); | ||
|
|
||
| // Set FrameLayout gravity based on positioning | ||
| FrameLayout.LayoutParams containerParams = new FrameLayout.LayoutParams( | ||
| FrameLayout.LayoutParams.MATCH_PARENT, | ||
| FrameLayout.LayoutParams.WRAP_CONTENT | ||
| ); | ||
|
|
||
| if (gravity == Gravity.CENTER_VERTICAL) { | ||
| containerParams.gravity = Gravity.CENTER; | ||
| IterableLogger.d(TAG, "Applied CENTER gravity to container"); | ||
| } else if (gravity == Gravity.TOP) { | ||
| containerParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; | ||
| IterableLogger.d(TAG, "Applied TOP gravity to container"); | ||
| } else if (gravity == Gravity.BOTTOM) { | ||
| containerParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; | ||
| IterableLogger.d(TAG, "Applied BOTTOM gravity to container"); | ||
| } | ||
|
|
||
| // Add WebView to the RelativeLayout container with WRAP_CONTENT for proper sizing | ||
| RelativeLayout.LayoutParams webViewParams = new RelativeLayout.LayoutParams( | ||
| RelativeLayout.LayoutParams.WRAP_CONTENT, | ||
| RelativeLayout.LayoutParams.WRAP_CONTENT | ||
| ); | ||
| webViewParams.addRule(RelativeLayout.CENTER_IN_PARENT); | ||
| webViewContainer.addView(webView, webViewParams); | ||
|
|
||
| IterableLogger.d(TAG, "Added WebView with WRAP_CONTENT and CENTER_IN_PARENT rule"); | ||
|
|
||
| // Add the container to the FrameLayout | ||
| frameLayout.addView(webViewContainer, containerParams); | ||
|
|
||
| IterableLogger.d(TAG, "Created FrameLayout with positioned RelativeLayout container"); | ||
|
|
||
| if (savedInstanceState == null || !savedInstanceState.getBoolean(IN_APP_OPEN_TRACKED, false)) { | ||
| IterableApi.sharedInstance.trackInAppOpen(messageId, location); | ||
| } | ||
|
|
||
| prepareToShowWebView(); | ||
| return relativeLayout; | ||
| return frameLayout; | ||
| } | ||
|
|
||
| public void setLoaded(boolean loaded) { | ||
|
|
@@ -226,6 +351,12 @@ | |
| public void onDestroy() { | ||
| super.onDestroy(); | ||
|
|
||
| // Clean up pending resize operations | ||
| if (resizeHandler != null && pendingResizeRunnable != null) { | ||
| resizeHandler.removeCallbacks(pendingResizeRunnable); | ||
| pendingResizeRunnable = null; | ||
| } | ||
|
|
||
| if (this.getActivity() != null && this.getActivity().isChangingConfigurations()) { | ||
| return; | ||
| } | ||
|
|
@@ -414,7 +545,50 @@ | |
|
|
||
| @Override | ||
| public void runResizeScript() { | ||
| resize(webView.getContentHeight()); | ||
| // Cancel any pending resize operation | ||
| if (pendingResizeRunnable != null) { | ||
| resizeHandler.removeCallbacks(pendingResizeRunnable); | ||
| } | ||
|
|
||
| // Schedule a debounced resize operation | ||
| pendingResizeRunnable = new Runnable() { | ||
| @Override | ||
| public void run() { | ||
| performResizeWithValidation(); | ||
| } | ||
| }; | ||
|
|
||
| resizeHandler.postDelayed(pendingResizeRunnable, RESIZE_DEBOUNCE_DELAY_MS); | ||
| } | ||
|
|
||
| private void performResizeWithValidation() { | ||
| if (webView == null) { | ||
| IterableLogger.w(TAG, "WebView is null, skipping resize"); | ||
| return; | ||
| } | ||
|
|
||
| float currentHeight = webView.getContentHeight(); | ||
|
|
||
| // Validate content height | ||
| if (currentHeight <= 0) { | ||
| IterableLogger.w(TAG, "Invalid content height: " + currentHeight + "dp, skipping resize"); | ||
| return; | ||
| } | ||
|
|
||
| // Check if height has stabilized (avoid unnecessary resizes for same height) | ||
| if (Math.abs(currentHeight - lastContentHeight) < 1.0f) { | ||
| IterableLogger.d(TAG, "Content height unchanged (" + currentHeight + "dp), skipping resize"); | ||
| return; | ||
| } | ||
|
|
||
| lastContentHeight = currentHeight; | ||
|
|
||
| IterableLogger.d( | ||
| TAG, | ||
| "💚 Resizing in-app to height: " + currentHeight + "dp" | ||
| ); | ||
|
|
||
| resize(currentHeight); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -462,9 +636,44 @@ | |
| window.setLayout(webViewWidth, webViewHeight); | ||
| getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); | ||
| } else { | ||
| // Resize the WebView directly with explicit size | ||
| float relativeHeight = height * getResources().getDisplayMetrics().density; | ||
| RelativeLayout.LayoutParams webViewLayout = new RelativeLayout.LayoutParams(getResources().getDisplayMetrics().widthPixels, (int) relativeHeight); | ||
| webView.setLayoutParams(webViewLayout); | ||
| int newWebViewWidth = getResources().getDisplayMetrics().widthPixels; | ||
| int newWebViewHeight = (int) relativeHeight; | ||
|
|
||
| // Set WebView to explicit size | ||
| RelativeLayout.LayoutParams webViewParams = new RelativeLayout.LayoutParams(newWebViewWidth, newWebViewHeight); | ||
|
|
||
| // Apply positioning based on gravity | ||
| int resizeGravity = getVerticalLocation(insetPadding); | ||
| IterableLogger.d(TAG, "Resizing WebView directly - gravity: " + resizeGravity + " size: " + newWebViewWidth + "x" + newWebViewHeight + "px for inset padding: " + insetPadding); | ||
|
|
||
| if (resizeGravity == Gravity.CENTER_VERTICAL) { | ||
| webViewParams.addRule(RelativeLayout.CENTER_IN_PARENT); | ||
| IterableLogger.d(TAG, "Applied CENTER_IN_PARENT to WebView"); | ||
| } else if (resizeGravity == Gravity.TOP) { | ||
| webViewParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); | ||
| webViewParams.addRule(RelativeLayout.CENTER_HORIZONTAL); | ||
| IterableLogger.d(TAG, "Applied TOP alignment to WebView"); | ||
| } else if (resizeGravity == Gravity.BOTTOM) { | ||
| webViewParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); | ||
| webViewParams.addRule(RelativeLayout.CENTER_HORIZONTAL); | ||
| IterableLogger.d(TAG, "Applied BOTTOM alignment to WebView"); | ||
| } | ||
|
|
||
| // Make dialog full screen to allow proper positioning | ||
| window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); | ||
|
|
||
| // Apply the new layout params to WebView | ||
| webView.setLayoutParams(webViewParams); | ||
|
|
||
| // Force layout updates | ||
| webView.requestLayout(); | ||
| if (webView.getParent() instanceof ViewGroup) { | ||
| ((ViewGroup) webView.getParent()).requestLayout(); | ||
| } | ||
|
|
||
| IterableLogger.d(TAG, "Applied explicit size and positioning to WebView: " + newWebViewWidth + "x" + newWebViewHeight); | ||
| } | ||
| } catch (IllegalArgumentException e) { | ||
| IterableLogger.e(TAG, "Exception while trying to resize an in-app message", e); | ||
|
|
||
Check notice
Code scanning / CodeQL
Deprecated method or constructor invocation Note