7
7
import android .content .Context ;
8
8
import android .graphics .Color ;
9
9
import android .graphics .drawable .ColorDrawable ;
10
+ import android .os .Build ;
10
11
import android .os .Handler ;
11
12
import android .support .annotation .NonNull ;
12
13
import android .support .annotation .Nullable ;
43
44
*/
44
45
class InAppMessageView {
45
46
47
+ private static final String IN_APP_MESSAGE_CARD_VIEW_TAG = "IN_APP_MESSAGE_CARD_VIEW_TAG" ;
48
+
46
49
private static final int ACTIVITY_BACKGROUND_COLOR_EMPTY = Color .parseColor ("#00000000" );
47
50
private static final int ACTIVITY_BACKGROUND_COLOR_FULL = Color .parseColor ("#BB000000" );
48
51
@@ -121,8 +124,8 @@ void updateHeight(final int pageHeight) {
121
124
public void run () {
122
125
if (webView == null ) {
123
126
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." );
126
129
return ;
127
130
}
128
131
@@ -156,10 +159,10 @@ void showInAppMessageView(Activity currentActivity) {
156
159
LinearLayout .LayoutParams linearLayoutParams = hasBackground ? createParentLinearLayoutParams () : null ;
157
160
158
161
showDraggableView (
159
- displayLocation ,
160
- webViewLayoutParams ,
161
- linearLayoutParams ,
162
- createDraggableLayoutParams (pageHeight , displayLocation )
162
+ displayLocation ,
163
+ webViewLayoutParams ,
164
+ linearLayoutParams ,
165
+ createDraggableLayoutParams (pageHeight , displayLocation )
163
166
);
164
167
}
165
168
@@ -227,7 +230,7 @@ private void showDraggableView(final WebViewManager.Position displayLocation,
227
230
@ Override
228
231
public void run () {
229
232
if (webView == null )
230
- return ;
233
+ return ;
231
234
232
235
webView .setLayoutParams (relativeLayoutParams );
233
236
@@ -241,51 +244,51 @@ public void run() {
241
244
messageController .onMessageWasShown ();
242
245
}
243
246
244
- startDismissTimerIfNeeded ();
245
- }
247
+ startDismissTimerIfNeeded ();
248
+ }
246
249
});
247
250
}
248
251
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
+ */
254
257
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
+ }
289
292
290
293
private void setUpParentLinearLayout (Context context ) {
291
294
parentRelativeLayout = new RelativeLayout (context );
@@ -320,9 +323,10 @@ public void onDragEnd() {
320
323
});
321
324
322
325
if (webView .getParent () != null )
323
- ((ViewGroup ) webView .getParent ()).removeAllViews ();
326
+ ((ViewGroup ) webView .getParent ()).removeAllViews ();
324
327
325
328
CardView cardView = createCardView (context );
329
+ cardView .setTag (IN_APP_MESSAGE_CARD_VIEW_TAG );
326
330
cardView .addView (webView );
327
331
328
332
draggableRelativeLayout .setPadding (MARGIN_PX_SIZE , MARGIN_PX_SIZE , MARGIN_PX_SIZE , MARGIN_PX_SIZE );
@@ -346,21 +350,27 @@ private CardView createCardView(Context context) {
346
350
CardView cardView = new CardView (context );
347
351
348
352
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 ;
351
355
RelativeLayout .LayoutParams cardViewLayoutParams = new RelativeLayout .LayoutParams (
352
- ViewGroup .LayoutParams .MATCH_PARENT ,
353
- height
356
+ ViewGroup .LayoutParams .MATCH_PARENT ,
357
+ height
354
358
);
355
359
cardViewLayoutParams .addRule (RelativeLayout .CENTER_IN_PARENT );
356
360
cardView .setLayoutParams (cardViewLayoutParams );
357
361
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 ));
360
368
369
+ cardView .setRadius (dpToPx (8 ));
361
370
cardView .setClipChildren (false );
362
371
cardView .setClipToPadding (false );
363
372
cardView .setPreventCornerOverlap (false );
373
+
364
374
return cardView ;
365
375
}
366
376
@@ -369,10 +379,10 @@ private CardView createCardView(Context context) {
369
379
*/
370
380
private void startDismissTimerIfNeeded () {
371
381
if (dismissDuration <= 0 )
372
- return ;
382
+ return ;
373
383
374
384
if (scheduleDismissRunnable != null )
375
- return ;
385
+ return ;
376
386
377
387
scheduleDismissRunnable = new Runnable () {
378
388
public void run () {
@@ -431,7 +441,7 @@ public void run() {
431
441
else {
432
442
cleanupViewsAfterDismiss ();
433
443
if (callback != null )
434
- callback .onComplete ();
444
+ callback .onComplete ();
435
445
}
436
446
}
437
447
}, ACTIVITY_FINISH_AFTER_DISMISS_DELAY_MS );
@@ -447,21 +457,21 @@ private void cleanupViewsAfterDismiss() {
447
457
messageController .onMessageWasDismissed ();
448
458
}
449
459
450
- /**
451
- * Remove all views and dismiss PopupWindow
452
- */
460
+ /**
461
+ * Remove all views and dismiss PopupWindow
462
+ */
453
463
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 ();
461
471
462
- if (popupWindow != null )
463
- popupWindow .dismiss ();
464
- dereferenceViews ();
472
+ if (popupWindow != null )
473
+ popupWindow .dismiss ();
474
+ dereferenceViews ();
465
475
}
466
476
467
477
/**
@@ -475,62 +485,86 @@ private void dereferenceViews() {
475
485
}
476
486
477
487
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
+
478
494
// Based on the location of the in app message apply and animation to match
479
495
switch (displayLocation ) {
480
496
case TOP_BANNER :
481
- View topBannerMessageViewChild = ((ViewGroup ) messageView ).getChildAt (0 );
482
- animateTop (topBannerMessageViewChild , webView .getHeight ());
497
+ animateTop (messageViewCardView , webView .getHeight (), cardViewAnimCallback );
483
498
break ;
484
499
case BOTTOM_BANNER :
485
- View bottomBannerMessageViewChild = ((ViewGroup ) messageView ).getChildAt (0 );
486
- animateBottom (bottomBannerMessageViewChild , webView .getHeight ());
500
+ animateBottom (messageViewCardView , webView .getHeight (), cardViewAnimCallback );
487
501
break ;
488
502
case CENTER_MODAL :
489
503
case FULL_SCREEN :
490
- animateCenter (messageView , backgroundView );
504
+ animateCenter (messageView , backgroundView , cardViewAnimCallback , null );
491
505
break ;
492
506
}
493
507
}
494
508
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 ) {
496
530
// Animate the message view from above the screen downward to the top
497
531
OneSignalAnimate .animateViewByTranslation (
498
532
messageView ,
499
533
-height - MARGIN_PX_SIZE ,
500
534
0f ,
501
535
IN_APP_BANNER_ANIMATION_DURATION_MS ,
502
536
new OneSignalBounceInterpolator (0.1 , 8.0 ),
503
- null )
537
+ cardViewAnimCallback )
504
538
.start ();
505
539
}
506
540
507
- private void animateBottom (View messageView , int height ) {
541
+ private void animateBottom (View messageView , int height , Animation . AnimationListener cardViewAnimCallback ) {
508
542
// Animate the message view from under the screen upward to the bottom
509
543
OneSignalAnimate .animateViewByTranslation (
510
544
messageView ,
511
545
height + MARGIN_PX_SIZE ,
512
546
0f ,
513
547
IN_APP_BANNER_ANIMATION_DURATION_MS ,
514
548
new OneSignalBounceInterpolator (0.1 , 8.0 ),
515
- null )
549
+ cardViewAnimCallback )
516
550
.start ();
517
551
}
518
552
519
- private void animateCenter (View messageView , final View backgroundView ) {
553
+ private void animateCenter (View messageView , final View backgroundView , Animation . AnimationListener cardViewAnimCallback , Animator . AnimatorListener backgroundAnimCallback ) {
520
554
// Animate the message view by scale since it settles at the center of the screen
521
555
Animation messageAnimation = OneSignalAnimate .animateViewSmallToLarge (
522
556
messageView ,
523
557
IN_APP_CENTER_ANIMATION_DURATION_MS ,
524
558
new OneSignalBounceInterpolator (0.1 , 8.0 ),
525
- null );
559
+ cardViewAnimCallback );
526
560
527
561
// Animate background behind the message so it doesn't just show the dark transparency
528
562
ValueAnimator backgroundAnimation = animateBackgroundColor (
529
563
backgroundView ,
530
564
IN_APP_BACKGROUND_ANIMATION_DURATION_MS ,
531
565
ACTIVITY_BACKGROUND_COLOR_EMPTY ,
532
566
ACTIVITY_BACKGROUND_COLOR_FULL ,
533
- null );
567
+ backgroundAnimCallback );
534
568
535
569
messageAnimation .start ();
536
570
backgroundAnimation .start ();
@@ -541,8 +575,8 @@ private void animateAndDismissLayout(View backgroundView, final WebViewManager.O
541
575
@ Override
542
576
public void onAnimationEnd (Animator animation ) {
543
577
cleanupViewsAfterDismiss ();
544
- if (callback != null )
545
- callback .onComplete ();
578
+ if (callback != null )
579
+ callback .onComplete ();
546
580
}
547
581
};
548
582
@@ -564,4 +598,4 @@ private ValueAnimator animateBackgroundColor(View backgroundView, int duration,
564
598
endColor ,
565
599
animCallback );
566
600
}
567
- }
601
+ }
0 commit comments