Skip to content

Commit f019b9b

Browse files
authored
Merge pull request #1105 from OneSignal/fix/iam_android_6_api_23_bug
Fix IAM showing bug with Android 6 API 23
2 parents 4678ff6 + 6d232cf commit f019b9b

File tree

1 file changed

+120
-86
lines changed

1 file changed

+120
-86
lines changed

OneSignalSDK/onesignal/src/main/java/com/onesignal/InAppMessageView.java

Lines changed: 120 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import android.content.Context;
88
import android.graphics.Color;
99
import android.graphics.drawable.ColorDrawable;
10+
import android.os.Build;
1011
import android.os.Handler;
1112
import android.support.annotation.NonNull;
1213
import android.support.annotation.Nullable;
@@ -43,6 +44,8 @@
4344
*/
4445
class InAppMessageView {
4546

47+
private static final String IN_APP_MESSAGE_CARD_VIEW_TAG = "IN_APP_MESSAGE_CARD_VIEW_TAG";
48+
4649
private static final int ACTIVITY_BACKGROUND_COLOR_EMPTY = Color.parseColor("#00000000");
4750
private static final int ACTIVITY_BACKGROUND_COLOR_FULL = Color.parseColor("#BB000000");
4851

@@ -121,8 +124,8 @@ void updateHeight(final int pageHeight) {
121124
public void run() {
122125
if (webView == null) {
123126
OneSignal.onesignalLog(
124-
OneSignal.LOG_LEVEL.WARN,
125-
"WebView height update skipped, new height will be used once it is displayed.");
127+
OneSignal.LOG_LEVEL.WARN,
128+
"WebView height update skipped, new height will be used once it is displayed.");
126129
return;
127130
}
128131

@@ -156,10 +159,10 @@ void showInAppMessageView(Activity currentActivity) {
156159
LinearLayout.LayoutParams linearLayoutParams = hasBackground ? createParentLinearLayoutParams() : null;
157160

158161
showDraggableView(
159-
displayLocation,
160-
webViewLayoutParams,
161-
linearLayoutParams,
162-
createDraggableLayoutParams(pageHeight, displayLocation)
162+
displayLocation,
163+
webViewLayoutParams,
164+
linearLayoutParams,
165+
createDraggableLayoutParams(pageHeight, displayLocation)
163166
);
164167
}
165168

@@ -227,7 +230,7 @@ private void showDraggableView(final WebViewManager.Position displayLocation,
227230
@Override
228231
public void run() {
229232
if (webView == null)
230-
return;
233+
return;
231234

232235
webView.setLayoutParams(relativeLayoutParams);
233236

@@ -241,51 +244,51 @@ public void run() {
241244
messageController.onMessageWasShown();
242245
}
243246

244-
startDismissTimerIfNeeded();
245-
}
247+
startDismissTimerIfNeeded();
248+
}
246249
});
247250
}
248251

249-
/**
250-
* Create a new Android PopupWindow that draws over the current Activity
251-
*
252-
* @param parentRelativeLayout root layout to attach to the pop up window
253-
*/
252+
/**
253+
* Create a new Android PopupWindow that draws over the current Activity
254+
*
255+
* @param parentRelativeLayout root layout to attach to the pop up window
256+
*/
254257
private void createPopupWindow(@NonNull RelativeLayout parentRelativeLayout) {
255-
popupWindow = new PopupWindow(
256-
parentRelativeLayout,
257-
hasBackground ? WindowManager.LayoutParams.MATCH_PARENT : pageWidth,
258-
hasBackground ? WindowManager.LayoutParams.MATCH_PARENT : WindowManager.LayoutParams.WRAP_CONTENT
259-
);
260-
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
261-
popupWindow.setTouchable(true);
262-
263-
int gravity = 0;
264-
if (!hasBackground) {
265-
switch (displayLocation) {
266-
case TOP_BANNER:
267-
gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
268-
break;
269-
case BOTTOM_BANNER:
270-
gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
271-
break;
272-
}
273-
}
274-
275-
// Using this instead of TYPE_APPLICATION_PANEL so the layout background does not get
276-
// cut off in immersive mode.
277-
PopupWindowCompat.setWindowLayoutType(
278-
popupWindow,
279-
WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG
280-
);
281-
282-
popupWindow.showAtLocation(
283-
currentActivity.getWindow().getDecorView().getRootView(),
284-
gravity,
285-
0,
286-
0
287-
);
288-
}
258+
popupWindow = new PopupWindow(
259+
parentRelativeLayout,
260+
hasBackground ? WindowManager.LayoutParams.MATCH_PARENT : pageWidth,
261+
hasBackground ? WindowManager.LayoutParams.MATCH_PARENT : WindowManager.LayoutParams.WRAP_CONTENT
262+
);
263+
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
264+
popupWindow.setTouchable(true);
265+
266+
int gravity = 0;
267+
if (!hasBackground) {
268+
switch (displayLocation) {
269+
case TOP_BANNER:
270+
gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
271+
break;
272+
case BOTTOM_BANNER:
273+
gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
274+
break;
275+
}
276+
}
277+
278+
// Using this instead of TYPE_APPLICATION_PANEL so the layout background does not get
279+
// cut off in immersive mode.
280+
PopupWindowCompat.setWindowLayoutType(
281+
popupWindow,
282+
WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG
283+
);
284+
285+
popupWindow.showAtLocation(
286+
currentActivity.getWindow().getDecorView().getRootView(),
287+
gravity,
288+
0,
289+
0
290+
);
291+
}
289292

290293
private void setUpParentLinearLayout(Context context) {
291294
parentRelativeLayout = new RelativeLayout(context);
@@ -320,9 +323,10 @@ public void onDragEnd() {
320323
});
321324

322325
if (webView.getParent() != null)
323-
((ViewGroup) webView.getParent()).removeAllViews();
326+
((ViewGroup) webView.getParent()).removeAllViews();
324327

325328
CardView cardView = createCardView(context);
329+
cardView.setTag(IN_APP_MESSAGE_CARD_VIEW_TAG);
326330
cardView.addView(webView);
327331

328332
draggableRelativeLayout.setPadding(MARGIN_PX_SIZE, MARGIN_PX_SIZE, MARGIN_PX_SIZE, MARGIN_PX_SIZE);
@@ -346,21 +350,27 @@ private CardView createCardView(Context context) {
346350
CardView cardView = new CardView(context);
347351

348352
int height = displayLocation == WebViewManager.Position.FULL_SCREEN ?
349-
ViewGroup.LayoutParams.MATCH_PARENT :
350-
ViewGroup.LayoutParams.WRAP_CONTENT;
353+
ViewGroup.LayoutParams.MATCH_PARENT :
354+
ViewGroup.LayoutParams.WRAP_CONTENT;
351355
RelativeLayout.LayoutParams cardViewLayoutParams = new RelativeLayout.LayoutParams(
352-
ViewGroup.LayoutParams.MATCH_PARENT,
353-
height
356+
ViewGroup.LayoutParams.MATCH_PARENT,
357+
height
354358
);
355359
cardViewLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
356360
cardView.setLayoutParams(cardViewLayoutParams);
357361

358-
cardView.setRadius(dpToPx(8));
359-
cardView.setCardElevation(dpToPx(5));
362+
// Set the initial elevation of the CardView to 0dp if using Android 6 API 23
363+
// Fixes bug when animating a elevated CardView class
364+
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M)
365+
cardView.setCardElevation(0);
366+
else
367+
cardView.setCardElevation(dpToPx(5));
360368

369+
cardView.setRadius(dpToPx(8));
361370
cardView.setClipChildren(false);
362371
cardView.setClipToPadding(false);
363372
cardView.setPreventCornerOverlap(false);
373+
364374
return cardView;
365375
}
366376

@@ -369,10 +379,10 @@ private CardView createCardView(Context context) {
369379
*/
370380
private void startDismissTimerIfNeeded() {
371381
if (dismissDuration <= 0)
372-
return;
382+
return;
373383

374384
if (scheduleDismissRunnable != null)
375-
return;
385+
return;
376386

377387
scheduleDismissRunnable = new Runnable() {
378388
public void run() {
@@ -431,7 +441,7 @@ public void run() {
431441
else {
432442
cleanupViewsAfterDismiss();
433443
if (callback != null)
434-
callback.onComplete();
444+
callback.onComplete();
435445
}
436446
}
437447
}, ACTIVITY_FINISH_AFTER_DISMISS_DELAY_MS);
@@ -447,21 +457,21 @@ private void cleanupViewsAfterDismiss() {
447457
messageController.onMessageWasDismissed();
448458
}
449459

450-
/**
451-
* Remove all views and dismiss PopupWindow
452-
*/
460+
/**
461+
* Remove all views and dismiss PopupWindow
462+
*/
453463
void removeAllViews() {
454-
if (scheduleDismissRunnable != null) {
455-
// Dismissed before the dismiss delay
456-
handler.removeCallbacks(scheduleDismissRunnable);
457-
scheduleDismissRunnable = null;
458-
}
459-
if (draggableRelativeLayout != null)
460-
draggableRelativeLayout.removeAllViews();
464+
if (scheduleDismissRunnable != null) {
465+
// Dismissed before the dismiss delay
466+
handler.removeCallbacks(scheduleDismissRunnable);
467+
scheduleDismissRunnable = null;
468+
}
469+
if (draggableRelativeLayout != null)
470+
draggableRelativeLayout.removeAllViews();
461471

462-
if (popupWindow != null)
463-
popupWindow.dismiss();
464-
dereferenceViews();
472+
if (popupWindow != null)
473+
popupWindow.dismiss();
474+
dereferenceViews();
465475
}
466476

467477
/**
@@ -475,62 +485,86 @@ private void dereferenceViews() {
475485
}
476486

477487
private void animateInAppMessage(WebViewManager.Position displayLocation, View messageView, View backgroundView) {
488+
final CardView messageViewCardView = messageView.findViewWithTag(IN_APP_MESSAGE_CARD_VIEW_TAG);
489+
490+
Animation.AnimationListener cardViewAnimCallback = null;
491+
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M)
492+
cardViewAnimCallback = createAnimationListenerForAndroidApi23Elevation(messageViewCardView);
493+
478494
// Based on the location of the in app message apply and animation to match
479495
switch (displayLocation) {
480496
case TOP_BANNER:
481-
View topBannerMessageViewChild = ((ViewGroup) messageView).getChildAt(0);
482-
animateTop(topBannerMessageViewChild, webView.getHeight());
497+
animateTop(messageViewCardView, webView.getHeight(), cardViewAnimCallback);
483498
break;
484499
case BOTTOM_BANNER:
485-
View bottomBannerMessageViewChild = ((ViewGroup) messageView).getChildAt(0);
486-
animateBottom(bottomBannerMessageViewChild, webView.getHeight());
500+
animateBottom(messageViewCardView, webView.getHeight(), cardViewAnimCallback);
487501
break;
488502
case CENTER_MODAL:
489503
case FULL_SCREEN:
490-
animateCenter(messageView, backgroundView);
504+
animateCenter(messageView, backgroundView, cardViewAnimCallback, null);
491505
break;
492506
}
493507
}
494508

495-
private void animateTop(View messageView, int height) {
509+
private Animation.AnimationListener createAnimationListenerForAndroidApi23Elevation(final CardView messageViewCardView) {
510+
return new Animation.AnimationListener() {
511+
@Override
512+
public void onAnimationStart(Animation animation) {
513+
514+
}
515+
516+
@Override
517+
public void onAnimationEnd(Animation animation) {
518+
// For Android 6 API 23 devices, waits until end of animation to set elevation of CardView class
519+
messageViewCardView.setCardElevation(dpToPx(5));
520+
}
521+
522+
@Override
523+
public void onAnimationRepeat(Animation animation) {
524+
525+
}
526+
};
527+
}
528+
529+
private void animateTop(View messageView, int height, Animation.AnimationListener cardViewAnimCallback) {
496530
// Animate the message view from above the screen downward to the top
497531
OneSignalAnimate.animateViewByTranslation(
498532
messageView,
499533
-height - MARGIN_PX_SIZE,
500534
0f,
501535
IN_APP_BANNER_ANIMATION_DURATION_MS,
502536
new OneSignalBounceInterpolator(0.1, 8.0),
503-
null)
537+
cardViewAnimCallback)
504538
.start();
505539
}
506540

507-
private void animateBottom(View messageView, int height) {
541+
private void animateBottom(View messageView, int height, Animation.AnimationListener cardViewAnimCallback) {
508542
// Animate the message view from under the screen upward to the bottom
509543
OneSignalAnimate.animateViewByTranslation(
510544
messageView,
511545
height + MARGIN_PX_SIZE,
512546
0f,
513547
IN_APP_BANNER_ANIMATION_DURATION_MS,
514548
new OneSignalBounceInterpolator(0.1, 8.0),
515-
null)
549+
cardViewAnimCallback)
516550
.start();
517551
}
518552

519-
private void animateCenter(View messageView, final View backgroundView) {
553+
private void animateCenter(View messageView, final View backgroundView, Animation.AnimationListener cardViewAnimCallback, Animator.AnimatorListener backgroundAnimCallback) {
520554
// Animate the message view by scale since it settles at the center of the screen
521555
Animation messageAnimation = OneSignalAnimate.animateViewSmallToLarge(
522556
messageView,
523557
IN_APP_CENTER_ANIMATION_DURATION_MS,
524558
new OneSignalBounceInterpolator(0.1, 8.0),
525-
null);
559+
cardViewAnimCallback);
526560

527561
// Animate background behind the message so it doesn't just show the dark transparency
528562
ValueAnimator backgroundAnimation = animateBackgroundColor(
529563
backgroundView,
530564
IN_APP_BACKGROUND_ANIMATION_DURATION_MS,
531565
ACTIVITY_BACKGROUND_COLOR_EMPTY,
532566
ACTIVITY_BACKGROUND_COLOR_FULL,
533-
null);
567+
backgroundAnimCallback);
534568

535569
messageAnimation.start();
536570
backgroundAnimation.start();
@@ -541,8 +575,8 @@ private void animateAndDismissLayout(View backgroundView, final WebViewManager.O
541575
@Override
542576
public void onAnimationEnd(Animator animation) {
543577
cleanupViewsAfterDismiss();
544-
if (callback != null)
545-
callback.onComplete();
578+
if (callback != null)
579+
callback.onComplete();
546580
}
547581
};
548582

@@ -564,4 +598,4 @@ private ValueAnimator animateBackgroundColor(View backgroundView, int duration,
564598
endColor,
565599
animCallback);
566600
}
567-
}
601+
}

0 commit comments

Comments
 (0)