diff --git a/README.md b/README.md index 31bf125..5e0b644 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,12 @@ [![npm](https://img.shields.io/npm/dt/react-native-smart-splash-screen.svg)](https://www.npmjs.com/package/react-native-smart-splash-screen) [![npm](https://img.shields.io/npm/l/react-native-smart-splash-screen.svg)](https://github.com/react-native-component/react-native-smart-splash-screen/blob/master/LICENSE) -A smart splash screen for React Native apps, written in JS, oc and java for cross-platform support. -It works on iOS and Android. +A smart splash screen for [React Native](https://github.com/facebook/react-native) apps, written in JS, oc and java for +cross-platform support. It works on iOS and Android. + + +##Tutorial for installation +(https://www.youtube.com/watch?v=XaKqek_m2mI) ## Preview @@ -21,7 +25,7 @@ npm install react-native-smart-splash-screen --save ## Notice -It can only be used greater-than-equal react-native 0.4.0 for ios, if you want to use the package less-than react-native 0.4.0, use `npm install react-native-smart-splash-screen@untilRN0.40 --save` +React-native-smart-splash-screen can only be used with react-native version >= 0.4.0 for ios, if you want to use the package with react-native version < 0.4.0, use `npm install react-native-smart-splash-screen@untilRN0.40 --save` ## Installation (iOS) @@ -33,6 +37,9 @@ It can only be used greater-than-equal react-native 0.4.0 for ios, if you want t * In your project, Look for Header Search Paths and make sure it contains $(SRCROOT)/../node_modules/react-native-smart-splash-screen/ios/RCTSplashScreen/RCTSplashScreen + +### Using an Image + * delete your project's LaunchScreen.xib * Drag SplashScreenResource folder to your project *if you want change image, replace splash.png or add a image with your custom name* @@ -63,6 +70,43 @@ return YES; ``` +### Using a Xib + +* Design your XIB in Xcode, setting proper autolayout constraints + +* Configure your project: + * Click on your main project file (the one that represents the .xcodeproj) + * Click on your Target + * Select "General" + * Scroll down to "App Icons and Launch Images" + * Set your "Launch Screen File" to the XIB you're using + +* In AppDelegate.m + +``` + +... +#import "RCTSplashScreen.h" //import interface +... +RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation + moduleName:@"ReactNativeComponents" + initialProperties:nil + launchOptions:launchOptions]; + +//[RCTSplashScreen open:rootView]; +[RCTSplashScreen open:rootView withXibNamed:@"LaunchScreen"]; // activate splashscreen, using LaunchScreen.xib + +rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; + +self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; +UIViewController *rootViewController = [UIViewController new]; +rootViewController.view = rootView; +self.window.rootViewController = rootViewController; +[self.window makeKeyAndVisible]; +return YES; + +``` + ## Installation (Android) @@ -133,6 +177,41 @@ protected void onCreate(Bundle savedInstanceState) { ... ``` +### Using an Image +Add splash.png to drawable@* folders + +### Using Custom Layout +Create splash_screen.xml file inside `res/layout` + +ex: +``` + + + + +``` + +Then modify onCreate method in MainActivity.java: + +```java + @Override + protected void onCreate(Bundle saveInstanceState) { + RCTSplashScreen.openSplashScreen(this, R.layout.splash_screen, true , ImageView.ScaleType.CENTER_INSIDE); + super.onCreate(saveInstanceState); + } +``` + + ## Full Demo see [ReactNativeComponentDemos][0] @@ -158,10 +237,10 @@ componentDidMount () { ## Method -* close(animationType, duration, delay) +* `close(animationType, duration, delay)` close splash screen with custom animation - * animationType: determine the type of animation. enum(animationType.none, animationType.fade, animationType.scale) + * animationType: determine the type of `animation.enum(animationType.none, animationType.fade, animationType.scale)` * duration: determine the duration of animation * delay: determine the delay of animation diff --git a/android/build.gradle b/android/build.gradle index dfbd150..5e8c1bf 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 23 - buildToolsVersion "23.0.3" + compileSdkVersion 26 + buildToolsVersion "27.0.3" defaultConfig { minSdkVersion 16 - targetSdkVersion 23 + targetSdkVersion 26 versionCode 1 versionName "1.0" } @@ -18,8 +18,20 @@ android { } } +buildscript { + repositories { + mavenCentral() + } +} +allprojects { + repositories { + mavenCentral() + } +} + dependencies { + compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.8' compile fileTree(include: ['*.jar'], dir: 'libs') - compile 'com.android.support:appcompat-v7:23.4.0' + compile 'com.android.support:appcompat-v7:26.1.0' compile 'com.facebook.react:react-native:+' } diff --git a/android/src/main/java/com/reactnativecomponent/splashscreen/RCTSplashScreen.java b/android/src/main/java/com/reactnativecomponent/splashscreen/RCTSplashScreen.java index 32c2e83..b29bddb 100644 --- a/android/src/main/java/com/reactnativecomponent/splashscreen/RCTSplashScreen.java +++ b/android/src/main/java/com/reactnativecomponent/splashscreen/RCTSplashScreen.java @@ -15,6 +15,8 @@ import java.lang.ref.WeakReference; +import pl.droidsonroids.gif.GifImageView; + public class RCTSplashScreen { @@ -23,7 +25,7 @@ public class RCTSplashScreen { public static final int UIAnimationScale = 2; private static Dialog dialog; - private static ImageView imageView; + private static GifImageView imageView; private static WeakReference wr_activity; @@ -31,15 +33,19 @@ protected static Activity getActivity() { return wr_activity.get(); } + protected static boolean hasActivity() { + return (wr_activity != null); + } + public static void openSplashScreen(Activity activity) { openSplashScreen(activity, false); } public static void openSplashScreen(Activity activity, boolean isFullScreen) { - openSplashScreen(activity, isFullScreen, ImageView.ScaleType.CENTER_CROP); + openSplashScreen(activity, isFullScreen, GifImageView.ScaleType.CENTER_CROP); } - public static void openSplashScreen(final Activity activity, final boolean isFullScreen, final ImageView.ScaleType scaleType) { + public static void openSplashScreen(final Activity activity, final boolean isFullScreen, final GifImageView.ScaleType scaleType) { if (activity == null) return; wr_activity = new WeakReference<>(activity); final int drawableId = getImageId(); @@ -49,9 +55,9 @@ public static void openSplashScreen(final Activity activity, final boolean isFul activity.runOnUiThread(new Runnable() { public void run() { - if(!getActivity().isFinishing()) { + if(hasActivity() && !getActivity().isFinishing()) { Context context = getActivity(); - imageView = new ImageView(context); + imageView = new GifImageView(context); imageView.setImageResource(drawableId); @@ -63,11 +69,6 @@ public void run() { dialog = new Dialog(context, isFullScreen ? android.R.style.Theme_Translucent_NoTitleBar_Fullscreen : android.R.style.Theme_Translucent_NoTitleBar); -// if ((getActivity().getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) -// == WindowManager.LayoutParams.FLAG_FULLSCREEN) { -// dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, -// WindowManager.LayoutParams.FLAG_FULLSCREEN); -// } dialog.setContentView(imageView); dialog.setCancelable(false); dialog.show(); @@ -77,10 +78,29 @@ public void run() { }); } + public static void openSplashScreen(final Activity activity, final int viewResource, final boolean isFullScreen, final GifImageView.ScaleType scaleType) { + if (activity == null) return; + wr_activity = new WeakReference<>(activity); + activity.runOnUiThread(new Runnable() { + public void run() { + if(hasActivity() && !getActivity().isFinishing()) { + Context context = getActivity(); + + dialog = new Dialog(context, isFullScreen ? android.R.style.Theme_Translucent_NoTitleBar_Fullscreen : android.R.style.Theme_Translucent_NoTitleBar); + dialog.setContentView(viewResource); + dialog.setCancelable(false); + dialog.show(); + } + + } + }); + } + public static void removeSplashScreen(Activity activity, final int animationType,final int duration) { - if (activity == null) { + if (hasActivity()) { activity = getActivity(); - if(activity == null) return; + } else { + return; } activity.runOnUiThread(new Runnable() { public void run() { @@ -122,9 +142,11 @@ public void onAnimationEnd(Animation animation) { view.post(new Runnable() { @Override public void run() { - dialog.dismiss(); - dialog = null; - imageView = null; + if (dialog != null && dialog.isShowing()) { + dialog.dismiss(); + dialog = null; + imageView = null; + } } }); } diff --git a/ios/RCTSplashScreen/RCTSplashScreen/RCTSplashScreen.h b/ios/RCTSplashScreen/RCTSplashScreen/RCTSplashScreen.h index 651b3f5..3f616e0 100644 --- a/ios/RCTSplashScreen/RCTSplashScreen/RCTSplashScreen.h +++ b/ios/RCTSplashScreen/RCTSplashScreen/RCTSplashScreen.h @@ -11,5 +11,6 @@ typedef NS_ENUM(NSInteger, RCTCameraAspect) { + (void)open:(RCTRootView *)v; + (void)open:(RCTRootView *)v withImageNamed:(NSString *)imgName; ++ (void)open:(RCTRootView *)v withXibNamed:(NSString *)xibName; @end diff --git a/ios/RCTSplashScreen/RCTSplashScreen/RCTSplashScreen.m b/ios/RCTSplashScreen/RCTSplashScreen/RCTSplashScreen.m index 278fefd..694e130 100644 --- a/ios/RCTSplashScreen/RCTSplashScreen/RCTSplashScreen.m +++ b/ios/RCTSplashScreen/RCTSplashScreen/RCTSplashScreen.m @@ -16,18 +16,30 @@ + (void)open:(RCTRootView *)v { [RCTSplashScreen open:v withImageNamed:@"splash"]; } - + (void)open:(RCTRootView *)v withImageNamed:(NSString *)imageName { - rootView = v; - UIImageView *view = [[UIImageView alloc]initWithFrame:[UIScreen mainScreen].bounds]; - + view.image = [UIImage imageNamed:imageName]; view.contentMode = UIViewContentModeScaleAspectFill; - [[NSNotificationCenter defaultCenter] removeObserver:rootView name:RCTContentDidAppearNotification object:rootView]; - - [rootView setLoadingView:view]; + [self open:v withView:view]; +} + ++ (void)open:(RCTRootView *)v withXibNamed:(NSString *)xibName { + NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:xibName owner:nil options:nil]; + + UIView *view = [nibContents lastObject]; + view.frame = rootView.bounds; + + [self open:v withView:view]; +} + ++ (void)open:(RCTRootView *)v withView:(UIView *)view { + rootView = v; + + [[NSNotificationCenter defaultCenter] removeObserver:rootView name:RCTContentDidAppearNotification object:rootView]; + + [rootView setLoadingView:view]; } RCT_EXPORT_METHOD(close:(NSDictionary *)options) { diff --git a/react-native-smart-splash-screen.podspec b/react-native-smart-splash-screen.podspec new file mode 100644 index 0000000..7d741ec --- /dev/null +++ b/react-native-smart-splash-screen.podspec @@ -0,0 +1,19 @@ +require 'json' + +package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) + +Pod::Spec.new do |s| + s.name = "react-native-smart-splash-screen" + s.version = package['version'] + s.summary = "React Native Smart Splash Screen component for Android and iOS" + + s.authors = { "henninghall" => "henning.hall@hotmail.com" } + s.homepage = "https://github.com/sam17896/react-native-smart-splash-screen" + s.license = package['license'] + s.platform = :ios, "8.0" + + s.source = { :git => "https://github.com/sam17896/react-native-smart-splash-screen" } + s.source_files = "ios/RCTSplashScreen/RCTSplashScreen/RCTSplashScreen.{h,m}" + + s.dependency 'React' +end