Reputation: 3966
We all know there is lots of tutorials about how to do a splash screen on Android. But we also know those are pseudo-splashscreens. I searched for many and I always saw Thread.sleep(x)
. That's not well coded, this is just to make the app beauty and looking like a professional app, that's not what I want!
Another problem with those splash screens is that they don't solve my problem because they only show it after the activity start and show the content view.
I have an app that does lots of things while initializing and when the app starts the user sees a black screen for a few seconds, enough time to annoy. So that's why I want to show a well-coded splash screen that removes that black screen that appears before the content view has been set.
I tried something. I included the splash screen (a RelativeLayout
) into the layout that is set in the MainActivity
, but as far as I know Android only shows the content after everything has been loaded, so if I'm trying to show some view from the content view I have to wait until everything has finished. Still, I'll send my code, it can help somehow...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new SplashTask().execute();
}
private class SplashTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
initializeViews();
mSplashScreen.setVisibility(View.VISIBLE);
}
@Override
protected Void doInBackground(Void... params) {
return null;
}
@Override
protected void onPostExecute(Void params) {
Standard.Initiate(MainActivity.this);
verifyListStats();
loadListAdapters();
setOnClickListeners();
mSplashScreen.setVisibility(View.GONE);
}
}
I tried to load some resources in doInBackground(...)
but because I do some operations in onResume()
that need those resources I can't do it (or at least I think I can't).
Any idea? I heard about a built-in mechanism similar to iOS launch images, perhaps that can be a way.
Upvotes: 7
Views: 2418
Reputation: 19290
Edit: Here is a great tutorial for splash screens where you want the splash screen to appear for a set amount of time, or for some processing to finish. It gives the pros/cons of several approaches as well.
http://blogactivity.wordpress.com/2012/02/24/writing-splash-screens-the-right-way/
Upvotes: 3
Reputation: 10203
When an activity is launched, Android starts a Zygote, an empty activity which does nothing, and sets your activity theme on it, then launches it. Once your activity is ready for display, it swaps the displayed activity to yours. For more info about Zygote, you can read this article by Cyril Motier
So to answer your question, you can do this :
That way, your "splash screen" (ie : the zygote with your splash theme) will be visible until your activity is ready to be displayed.
Upvotes: 5
Reputation: 23596
Below is the Splash Screen Activity which i am using in all Project. Please check if it is helpful to you.
public class SplashActivity extends Activity {
private SharedPreferences myPrefs;
private SharedPreferences.Editor prefsEditor;
private boolean login;
private boolean connectivityState;
private String connectedNetworkType;
private ConnectivityManager connectivityManager;
private CheckInternet checkInternet;
private File file = new File(API.file_dir);
public static Location loc;
Configuration newConfig;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_layout);
//----------------------
myPrefs = getSharedPreferences("myPrefs", MODE_WORLD_READABLE);
boolean login = myPrefs.getBoolean("login", false);
checkForInternetAndNextFlow();
}
// Check for the Internet Connection
private void checkForInternetAndNextFlow() {
connectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
checkInternet = new CheckInternet(getApplicationContext());
connectivityState = checkInternet.isConnected(connectivityManager);
if (connectivityState) {
connectedNetworkType = checkInternet.getNetworkType();
// Toast.makeText(getApplicationContext(), "Connected via : " +
// connectedNetworkType, Toast.LENGTH_LONG).show();
// check for the login or not from preference
myPrefs = this.getSharedPreferences("myPrefs", MODE_WORLD_READABLE);
login = myPrefs.getBoolean("login", false);
System.out.println("Loging value is:" + login);
Thread t = new Thread() {
public void run() {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (login) {
Intent i = new Intent(SplashActivity.this,MainTabActivity.class);
startActivity(i);
} else {
Intent i = new Intent(SplashActivity.this,LoginActivity.class);
startActivity(i);
}
}
}
};
t.start();
} else {
// Toast.makeText(getApplicationContext(), "NOT connected",
// Toast.LENGTH_LONG).show();
final Dialog dialog = new Dialog(SplashActivity.this,R.style.CustomDialogTheme);
dialog.getWindow();
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.internet_dialog);
dialog.setCancelable(false);
Button retryBtn = (Button) dialog.findViewById(R.id.retryBtn);
Button cancel = (Button) dialog.findViewById(R.id.cancelBtn);
retryBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
dialog.dismiss();
checkForInternetAndNextFlow();
}
});
cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
dialog.dismiss();
finish();
}
});
dialog.show();
}
}
}
Hope it will help you. Enjoy Coding... :)
Upvotes: 0
Reputation: 1786
One of my non-licensed projects required a splash screen even though it was not necessary. Maybe it can be useful to your project as it is based on a dialog rather than an activity. If the splash screen is tapped or gestured, it will be dismissed as well as once it is finished with the Animation (timed fadeout). Modifications could be made to the class so that you check some kind of "ready state boolean" before allowing tap or gestures to dismiss the image.
class file: AppIntro.java
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
public class AppIntro extends Dialog {
protected int mLayoutRes = 0;
protected int mAnimRes = 0;
protected Animation mIntroAnim = null;
protected View mLayout = null;
public AppIntro(Context aContext, int aLayoutRes, int aAnimRes) {
super(aContext);
mLayoutRes = aLayoutRes;
mAnimRes = aAnimRes;
}
@Override
protected void onCreate(Bundle aSavedState) {
super.onCreate(aSavedState);
mLayout = LayoutInflater.from(getContext()).inflate(mLayoutRes,null);
mLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AppIntro.this.dismiss();
}
});
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(mLayout);
mIntroAnim = AnimationUtils.loadAnimation(getContext(),mAnimRes);
mIntroAnim.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
//nothing to do
}
@Override
public void onAnimationRepeat(Animation animation) {
//nothing to do
}
@Override
public void onAnimationEnd(Animation animation) {
AppIntro.this.dismiss();
}
});
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
dismiss();
return true;
}
@Override
public void show() {
super.show();
mLayout.startAnimation(mIntroAnim);
}
}
Next, we define our animation fade out (change the duration to be what you need to load your app) in the file "res/anim/intro_anim.xml". 4200 = 4.2 seconds.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
>
<alpha
android:fromAlpha="1.0" android:toAlpha="0.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:duration="4200"
android:repeatCount="0" >
</alpha>
</set>
Finally, we define our splash screen layout (using whatever image(s) you want) in "layout/intro.xml". My particular splash screen showed an app title with image along with 3 logos from various funding sources.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_intro"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/intro_Text_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:gravity="center"
android:text="@string/title_intro"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ImageView
android:id="@+id/intro_Image_myproject"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/intro_Text_title"
android:layout_centerHorizontal="true"
android:src="@drawable/intro_image" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/intro_Image_myproject"
android:layout_alignRight="@id/intro_Image_myproject"
android:layout_alignLeft="@id/intro_Image_myproject">
<ImageView
android:id="@+id/intro_Image_logo1"
android:layout_width="80dp"
android:layout_height="50dp"
android:scaleType="fitXY"
android:src="@drawable/logo1"
android:layout_gravity="left|center_vertical"/>
<ImageView
android:id="@+id/intro_Image_logo2"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:src="@drawable/logo2"
android:layout_gravity="center"
android:scaleType="centerInside"/>
<ImageView
android:id="@+id/intro_Image_logo3"
android:layout_width="70dp"
android:layout_height="70dp"
android:scaleType="fitXY"
android:src="@drawable/logo3"
android:layout_gravity="right|center_vertical"/>
</FrameLayout>
</RelativeLayout>
The code used to popup the dialog:
@Override
protected void onCreate(Bundle aSavedState) {
super.onCreate(aSavedState);
if (aSavedState==null) {
//only show splash screen at app start, not on rotate screen
new AppIntro(this,R.layout.intro,R.anim.intro_anim).show();
}
setContentView(R.layout.main);
//...rest of onCreate()
}
My app displayed my main view at the same time as the splash screen, so no guarantee this dialog will show up as soon as you call .show().
Upvotes: 0
Reputation: 5263
I was also searching for the same. In the end I implement this which fullfill ol my requirements.
Note :
onStart()
is called.onCreate()
if you want some code runs only once in application lifetime.This is splash screen xml :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/splash_screen"
tools:context=".SplashScreenActivity">
</RelativeLayout>
This is Activity Class
public class SplashScreenActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent mainIntent = new Intent(SplashScreenActivity.this,
MyLauncherActivity.class);
SplashScreenActivity.this.startActivity(mainIntent);
// SplashScreenActivity.this.finish(); No need to finish it as "noHistory" tag is true in the manifest
}
}, 1500);
}
@Override
public void onBackPressed() {
}
}
Entries in the manifest :
<activity
android:name="com.wokomoco.test.activities.SplashScreenActivity"
android:label="@string/app_name"
android:noHistory="true"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Hope this will help you out. Enjoy coding!!
Upvotes: 0
Reputation: 301
The best way to open a splash screen is you can create a new activity for that and then in that activity you can set a timer to open a new activity which would be your main activity.I think using this you can get rid out of your black screen at start.In manifest make splash activity as your default launch activity.Here is the example :-
SplashActivity.java
public class SplashActivity extends Activity {
private Timer timer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_splash_activity);
}
@Override
protected void onResume() {
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Intent intialScreenIntent = new Intent(SplashActivity.this, MainActivity.class);
startActivity(intialScreenIntent);
}
}, 2000l);
super.onResume();
}
@Override
public void onBackPressed() {
try {
timer.cancel();
timer = null;
} catch (Exception e) {
}
super.onBackPressed();
}}
Upvotes: 0
Reputation: 4403
Create a SplashScreen activity and declare it as default in your app, i.e. add this to your AndroidManifest.xml
<activity
android:name="package.SplashScreen"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
In your SplashActivity onCreate launch a new AsyncTask:
public class SplashScreen extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_image);
new InitAsyncTask().execute();
}
private class InitAsyncTask extends AsyncTask<?, ?, ?> {
protected ? doInBackground(?... params) {
// PERFORM YOUR INITIALIZATION HERE
}
protected void onPostExecute(? result) {
// Initialization is completed, close SplashScreen
// and launch your MainActivity:
SplashScreen.this.finish();
startActivity(new Intent(MainActivity.class, SplashScreen.this);
}
}
}
Upvotes: 2
Reputation: 717
I have done this by creating a full screen splash dialog then close it when I was done loading
splashDialog = new Dialog(getActivity(), android.R.style.Theme_Black_NoTitleBar_Fullscreen);
splashDialog.setContentView(R.layout.yourSplashLayout);
Upvotes: 0