27
27
import android .util .Log ;
28
28
import android .view .SurfaceView ;
29
29
import android .view .ViewGroup ;
30
+ import android .view .View ;
30
31
import android .widget .ImageView ;
31
32
import android .widget .Toast ;
33
+ import android .content .res .Resources .NotFoundException ;
32
34
33
35
import org .libsdl .app .SDLActivity ;
34
36
@@ -61,7 +63,7 @@ protected void onCreate(Bundle savedInstanceState) {
61
63
Log .v (TAG , "Did super onCreate" );
62
64
63
65
this .mActivity = this ;
64
- this .showLoadingScreen ();
66
+ this .showLoadingScreen (this . getLoadingScreen () );
65
67
66
68
new UnpackFilesTask ().execute (getAppRoot ());
67
69
}
@@ -121,7 +123,7 @@ protected void onPostExecute(String result) {
121
123
// removed the loading screen. However, we still need it to
122
124
// show until the app is ready to render, so pop it back up
123
125
// on top of the SDL view.
124
- mActivity .showLoadingScreen ();
126
+ mActivity .showLoadingScreen (getLoadingScreen () );
125
127
126
128
String app_root_dir = getAppRoot ();
127
129
if (getIntent () != null && getIntent ().getAction () != null &&
@@ -338,6 +340,7 @@ public static void stop_service() {
338
340
339
341
/** Loading screen view **/
340
342
public static ImageView mImageView = null ;
343
+ public static View mLottieView = null ;
341
344
/** Whether main routine/actual app has started yet **/
342
345
protected boolean mAppConfirmedActive = false ;
343
346
/** Timer for delayed loading screen removal. **/
@@ -404,11 +407,11 @@ public void run() {
404
407
public void removeLoadingScreen () {
405
408
runOnUiThread (new Runnable () {
406
409
public void run () {
407
- if ( PythonActivity . mImageView != null &&
408
- PythonActivity . mImageView .getParent () != null ) {
409
- ((ViewGroup )PythonActivity . mImageView . getParent ()).removeView (
410
- PythonActivity . mImageView ) ;
411
- PythonActivity . mImageView = null ;
410
+ View view = mLottieView != null ? mLottieView : mImageView ;
411
+ if ( view != null && view .getParent () != null ) {
412
+ ((ViewGroup )view . getParent ()).removeView (view );
413
+ mLottieView = null ;
414
+ mImageView = null ;
412
415
}
413
416
}
414
417
});
@@ -430,65 +433,97 @@ public String getEntryPoint(String search_dir) {
430
433
return "main.py" ;
431
434
}
432
435
433
- protected void showLoadingScreen () {
436
+ protected void showLoadingScreen (View view ) {
437
+ try {
438
+ if (mLayout == null ) {
439
+ setContentView (view );
440
+ } else if (view .getParent () == null ) {
441
+ mLayout .addView (view );
442
+ }
443
+ } catch (IllegalStateException e ) {
444
+ // The loading screen can be attempted to be applied twice if app
445
+ // is tabbed in/out, quickly.
446
+ // (Gives error "The specified child already has a parent.
447
+ // You must call removeView() on the child's parent first.")
448
+ }
449
+ }
450
+
451
+ protected View getLoadingScreen () {
434
452
// load the bitmap
435
453
// 1. if the image is valid and we don't have layout yet, assign this bitmap
436
454
// as main view.
437
455
// 2. if we have a layout, just set it in the layout.
438
456
// 3. If we have an mImageView already, then do nothing because it will have
439
457
// already been made the content view or added to the layout.
440
458
441
- if (mImageView == null ) {
442
- int presplashId = this .resourceManager .getIdentifier ("presplash" , "drawable" );
443
- InputStream is = this .getResources ().openRawResource (presplashId );
444
- Bitmap bitmap = null ;
459
+ if (mLottieView != null || mImageView != null ) {
460
+ // we already have a splash screen
461
+ return mLottieView != null ? mLottieView : mImageView ;
462
+ }
463
+
464
+ // first try to load the lottie one
465
+ try {
466
+ mLottieView = getLayoutInflater ().inflate (
467
+ this .resourceManager .getIdentifier ("lottie" , "layout" ),
468
+ mLayout ,
469
+ false
470
+ );
445
471
try {
446
- bitmap = BitmapFactory .decodeStream (is );
447
- } finally {
448
- try {
449
- is .close ();
450
- } catch (IOException e ) {};
472
+ if (mLayout == null ) {
473
+ setContentView (mLottieView );
474
+ } else if (PythonActivity .mLottieView .getParent () == null ) {
475
+ mLayout .addView (mLottieView );
476
+ }
477
+ } catch (IllegalStateException e ) {
478
+ // The loading screen can be attempted to be applied twice if app
479
+ // is tabbed in/out, quickly.
480
+ // (Gives error "The specified child already has a parent.
481
+ // You must call removeView() on the child's parent first.")
451
482
}
452
-
453
- mImageView = new ImageView (this );
454
- mImageView .setImageBitmap (bitmap );
455
-
456
- /*
457
- * Set the presplash loading screen background color
458
- * https://developer.android.com/reference/android/graphics/Color.html
459
- * Parse the color string, and return the corresponding color-int.
460
- * If the string cannot be parsed, throws an IllegalArgumentException exception.
461
- * Supported formats are: #RRGGBB #AARRGGBB or one of the following names:
462
- * 'red', 'blue', 'green', 'black', 'white', 'gray', 'cyan', 'magenta', 'yellow',
463
- * 'lightgray', 'darkgray', 'grey', 'lightgrey', 'darkgrey', 'aqua', 'fuchsia',
464
- * 'lime', 'maroon', 'navy', 'olive', 'purple', 'silver', 'teal'.
465
- */
466
- String backgroundColor = resourceManager .getString ("presplash_color" );
467
- if (backgroundColor != null ) {
468
- try {
469
- mImageView .setBackgroundColor (Color .parseColor (backgroundColor ));
470
- } catch (IllegalArgumentException e ) {}
471
- }
472
- mImageView .setLayoutParams (new ViewGroup .LayoutParams (
473
- ViewGroup .LayoutParams .FILL_PARENT ,
474
- ViewGroup .LayoutParams .FILL_PARENT ));
475
- mImageView .setScaleType (ImageView .ScaleType .FIT_CENTER );
483
+ return mLottieView ;
484
+ }
485
+ catch (NotFoundException e ) {
486
+ Log .v ("SDL" , "couldn't find lottie layout or animation, trying static splash" );
476
487
}
477
488
489
+ // try to load the static image then
490
+ int presplashId = this .resourceManager .getIdentifier ("presplash" , "drawable" );
491
+ InputStream is = this .getResources ().openRawResource (presplashId );
492
+ Bitmap bitmap = null ;
478
493
try {
479
- if (mLayout == null ) {
480
- setContentView (mImageView );
481
- } else if (PythonActivity .mImageView .getParent () == null ) {
482
- mLayout .addView (mImageView );
483
- }
484
- } catch (IllegalStateException e ) {
485
- // The loading screen can be attempted to be applied twice if app
486
- // is tabbed in/out, quickly.
487
- // (Gives error "The specified child already has a parent.
488
- // You must call removeView() on the child's parent first.")
494
+ bitmap = BitmapFactory .decodeStream (is );
495
+ } finally {
496
+ try {
497
+ is .close ();
498
+ } catch (IOException e ) {};
489
499
}
500
+
501
+ mImageView = new ImageView (this );
502
+ mImageView .setImageBitmap (bitmap );
503
+
504
+ /*
505
+ * Set the presplash loading screen background color
506
+ * https://developer.android.com/reference/android/graphics/Color.html
507
+ * Parse the color string, and return the corresponding color-int.
508
+ * If the string cannot be parsed, throws an IllegalArgumentException exception.
509
+ * Supported formats are: #RRGGBB #AARRGGBB or one of the following names:
510
+ * 'red', 'blue', 'green', 'black', 'white', 'gray', 'cyan', 'magenta', 'yellow',
511
+ * 'lightgray', 'darkgray', 'grey', 'lightgrey', 'darkgrey', 'aqua', 'fuchsia',
512
+ * 'lime', 'maroon', 'navy', 'olive', 'purple', 'silver', 'teal'.
513
+ */
514
+ String backgroundColor = resourceManager .getString ("presplash_color" );
515
+ if (backgroundColor != null ) {
516
+ try {
517
+ mImageView .setBackgroundColor (Color .parseColor (backgroundColor ));
518
+ } catch (IllegalArgumentException e ) {}
519
+ }
520
+ mImageView .setLayoutParams (new ViewGroup .LayoutParams (
521
+ ViewGroup .LayoutParams .FILL_PARENT ,
522
+ ViewGroup .LayoutParams .FILL_PARENT ));
523
+ mImageView .setScaleType (ImageView .ScaleType .FIT_CENTER );
524
+ return mImageView ;
490
525
}
491
-
526
+
492
527
@ Override
493
528
protected void onPause () {
494
529
if (this .mWakeLock != null && mWakeLock .isHeld ()) {
0 commit comments