Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ public class MainActivity extends ReactActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
SplashScreen.show(this); // here
// SplashScreen.showVideo(this); // alternative
super.onCreate(savedInstanceState);
}
// ...other code
Expand All @@ -150,6 +151,7 @@ Update `AppDelegate.m` with the following additions:
// ...other code

[RNSplashScreen show]; // here
// [RNSplashScreen showVideo]; // alternative
// or
//[RNSplashScreen showSplash:@"LaunchScreen" inRootView:rootView];
return YES;
Expand All @@ -167,6 +169,8 @@ Import `react-native-splash-screen` in your JS file.

### Android:

#### Image Splashscreen

Create a file called `launch_screen.xml` in `app/src/main/res/layout` (create the `layout`-folder if it doesn't exist). The contents of the file should be the following:

```xml
Expand Down Expand Up @@ -196,6 +200,9 @@ Add a color called `primary_dark` in `app/src/main/res/values/colors.xml`
</resources>
```

#### Video Splashscreen

Customize your launch screen by creating a `splashscreen`-video-file and placing it in `raw`-folder.

**Optional steps:**

Expand Down Expand Up @@ -244,10 +251,16 @@ SplashScreen.show(this, R.style.SplashScreenTheme);

### iOS

#### Image Splashscreen

Customize your splash screen via `LaunchImage` or `LaunchScreen.xib`,

**Learn more to see [examples](https://github.com/crazycodeboy/react-native-splash-screen/tree/master/examples)**

#### Video Splashscreen

Add `splashscreen.mp4` to resources.

## Usage

Use like so:
Expand All @@ -261,6 +274,7 @@ export default class WelcomePage extends Component {
// do stuff while splash screen is shown
// After having done stuff (such as async tasks) hide the splash screen
SplashScreen.hide();
// SplashScreen.hideVideo(); // alternative
}
}
```
Expand Down
Binary file added android/src/.DS_Store
Binary file not shown.
Binary file added android/src/main/.DS_Store
Binary file not shown.
133 changes: 132 additions & 1 deletion android/src/main/java/org/devio/rn/splashscreen/SplashScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Build;
import android.view.View;
import android.graphics.Color;
import android.util.Log;
import android.media.MediaPlayer;
import android.view.ViewGroup;
import android.widget.VideoView;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.ReadableMap;
Expand All @@ -22,13 +30,125 @@
public class SplashScreen {
private static Dialog mSplashDialog;
private static WeakReference<Activity> mActivity;
private static boolean isVideoActive = false;
private static boolean isImageActive = false;
private static VideoView lastVideoView = null;
private static Runnable videoPauseRunnable = null;

public static void showVideo(final Activity activity) {
showVideo(activity, Arguments.createMap());
}

public static void showVideo(final Activity activity, final ReadableMap options) {
if (activity == null) return;
if (mSplashDialog != null) return;
if (isImageActive || isVideoActive) return;
isVideoActive = true;

mActivity = new WeakReference<Activity>(activity);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (!activity.isFinishing()) {
mSplashDialog = new Dialog(activity, R.style.SplashScreen_Fullscreen);
mSplashDialog.setContentView(R.layout.video_view);
mSplashDialog.setCancelable(false);

Context context = activity.getApplicationContext();

String videoPath = "android.resource://" + context.getPackageName() + "/" + R.raw.splashscreen;

MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(context, Uri.parse(videoPath));
int videoWidth = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
int videoHeight = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
retriever.release();


VideoView videoView = (VideoView) mSplashDialog.findViewById(R.id.video_view);
float viewHeight = videoView.getHeight();
float viewWidth = videoView.getWidth();

float ratioWidth = viewWidth / videoWidth;
float ratioHeight = viewHeight / videoHeight;
int fullWidth;
int fullHeight;
if (ratioWidth < ratioHeight) {
fullWidth = (int) (videoWidth * ratioWidth);
fullHeight = (int) (videoHeight * ratioWidth);
} else {
fullWidth = (int) (videoWidth * ratioHeight);
fullHeight = (int) (videoHeight * ratioHeight);
}

videoView.getLayoutParams().width = fullWidth;
videoView.getLayoutParams().height = fullHeight;

videoView.setVideoPath(videoPath);
videoView.start();

lastVideoView = videoView;

int pauseAfterMs = options.hasKey("pauseAfterMs") ? options.getInt("pauseAfterMs") : 0;
if (pauseAfterMs > 0) {
videoPauseRunnable = new Runnable() {
@Override
public void run() {
if (lastVideoView != null) {
lastVideoView.pause();
}
}
};
videoView.postDelayed(videoPauseRunnable, pauseAfterMs);
}

if (!mSplashDialog.isShowing()) {
mSplashDialog.show();
}

videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
resumeVideo(activity);
}
});
}
}
});
}

public static void removeVideoPauseOption(Activity activity) {
if (isImageActive) return;
if (lastVideoView == null || videoPauseRunnable == null) return;

lastVideoView.removeCallbacks(videoPauseRunnable);
videoPauseRunnable = null;
}

public static void resumeVideo(Activity activity) {
if (isImageActive) return;
if (lastVideoView == null) return;
removeVideoPauseOption(activity);

lastVideoView.start();
}

public static void hideVideo(Activity activity) {
if (isImageActive) return;

removeVideoPauseOption(activity);
lastVideoView = null;
_hide(activity, Arguments.createMap());
}

/**
* 打开启动屏
*/
public static void show(final Activity activity, final ReadableMap options) {
if (activity == null) return;
if (mSplashDialog != null) return;
if (isImageActive || isVideoActive) return;
isImageActive = true;

mActivity = new WeakReference<Activity>(activity);
activity.runOnUiThread(new Runnable() {
Expand Down Expand Up @@ -65,6 +185,11 @@ public static void show(final Activity activity) {
* 关闭启动屏
*/
public static void hide(Activity activity, final ReadableMap options) {
if (isVideoActive) return;
_hide(activity, options);
}

private static void _hide(Activity activity, final ReadableMap options) {
if (activity == null) {
if (mActivity == null) {
return;
Expand All @@ -87,7 +212,11 @@ public void run() {
}

if (!_activity.isFinishing() && !isDestroyed) {
mSplashDialog.dismiss();
try {
mSplashDialog.dismiss();
} catch (Exception e) {
Log.d("RNSplashScreen error on dismiss", e.getMessage());
}
}
mSplashDialog = null;
}
Expand All @@ -96,6 +225,8 @@ public void run() {
if (bgColor != null) {
setBackgroundColorSync(_activity, bgColor);
}
isImageActive = false;
isVideoActive = false;
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,33 @@ public void hide(ReadableMap options) {
SplashScreen.hide(getCurrentActivity(), options);
}

@ReactMethod
public void showVideo(ReadableMap options) {
SplashScreen.showVideo(getCurrentActivity(), options);
}

@ReactMethod
public void showVideo() {
showVideo(Arguments.createMap());
}

@ReactMethod
public void hideVideo() {
SplashScreen.hideVideo(getCurrentActivity());
}

@ReactMethod
public void setBackgroundColor(String color) {
SplashScreen.setBackgroundColor(getCurrentActivity(), color);
}

@ReactMethod
public void removeVideoPauseOption() {
SplashScreen.removeVideoPauseOption(getCurrentActivity());
}

@ReactMethod
public void resumeVideo() {
SplashScreen.resumeVideo(getCurrentActivity());
}
}
Binary file added android/src/main/res/.DS_Store
Binary file not shown.
15 changes: 15 additions & 0 deletions android/src/main/res/layout/video_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<VideoView
android:id="@+id/video_view"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
>
</VideoView>
</RelativeLayout>
3 changes: 3 additions & 0 deletions android/src/main/res/values/refs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@
<item type="layout" name="launch_screen">
@layout/launch_screen
</item>
<item type="raw" name="splashscreen">
@raw/splashscreen
</item>
</resources>
4 changes: 4 additions & 0 deletions index.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ const Wrapper = {
...SplashScreen,
show: (opts = {}) => SplashScreen.show(opts),
hide: (opts = {}) => SplashScreen.hide(opts),
showVideo: (opts = {}) => SplashScreen.showVideo(opts),
hideVideo: () => SplashScreen.hideVideo(),
resumeVideo: () => SplashScreen.resumeVideo(),
removeVideoPauseOption: () => SplashScreen.removeVideoPauseOption(),
}

export default Wrapper
3 changes: 3 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@ declare module "react-native-splash-screen" {
export default class SplashScreen {
static hide(): void;
static show(): void;
static showVideo(): void;
static hideVideo(): void;
static resumeVideo(): void;
}
}
4 changes: 4 additions & 0 deletions index.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ const Wrapper = {
// no opts supported
show: () => SplashScreen.show(),
hide: () => SplashScreen.hide(),
showVideo: (opts) => SplashScreen.showVideo(opts),
hideVideo: () => SplashScreen.hideVideo(),
resumeVideo: () => SplashScreen.resumeVideo(),
removeVideoPauseOption: () => SplashScreen.removeVideoPauseOption(),
}

export default Wrapper
5 changes: 5 additions & 0 deletions ios/RNSplashScreen.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,9 @@
@interface RNSplashScreen : NSObject<RCTBridgeModule>
+ (void)show;
+ (void)hide;
+ (void)showVideo;
+ (void)showVideo:(NSDictionary *)config;
+ (void)hideVideo;
+ (void)resumeVideo;
+ (void)removeVideoPauseOption;
@end
Loading