Ho bisogno di una schermata iniziale per la mia applicazione. Provato a creare un'attività con l'immagine per la mia schermata iniziale; e ho provato ad usare per loop e la classe Timer per introdurre un ritardo temporale. Ma non funziona in questo modo. Sto sbagliando; se sì, qual è la strada giusta?Il modo migliore per avere una schermata iniziale in un'applicazione Android?
risposta
Le soluzioni di cui sopra sono buone, ma cosa succede se l'utente preme il tasto indietro (e chiude l'app) prima che il ritardo dello splash sia terminato. L'app probabilmente aprirà ancora l'attività successiva, che non è molto intuitiva.
Ecco perché lavoro con un gestore personalizzato e rimuovo tutti i messaggi in sospeso in onDestroy().
public class SplashActivity extends Activity
{
private final static int MSG_CONTINUE = 1234;
private final static long DELAY = 2000;
@Override
protected void onCreate(Bundle args)
{
super.onCreate(args);
setContentView(R.layout.activity_splash);
mHandler.sendEmptyMessageDelayed(MSG_CONTINUE, DELAY);
}
@Override
protected void onDestroy()
{
mHandler.removeMessages(MSG_CONTINUE);
super.onDestroy();
}
private void _continue()
{
startActivity(new Intent(this, SomeOtherActivity.class));
finish();
}
private final Handler mHandler = new Handler()
{
public void handleMessage(android.os.Message msg)
{
switch(msg.what){
case MSG_CONTINUE:
_continue();
break;
}
}
};
}
Penso che onPause sia un'opzione migliore per la chiamata removeMessages(). Ho scoperto che onDestroy viene chiamato troppo tardi nel ciclo di vita e la successiva attività appare dopo aver cliccato indietro. +1 però :-) – barry
Si potrebbe semplicemente ritardare?
Thread delay = new Thread() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
runOnUiThread(new Runnable() {
@Override
public void run() {
startNextActivity();
}
});
}
};
Prova questo
public class SplashActivity extends Activity {
Handler handler;
private long timeDelay = 2000; //2 seconds
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.SplashLayout);
final Intent i = new Intent(this, Landing.class);
handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
startActivity(i);
finish();
}
}, timeDelay);
}
}
Prova questa,
protected int _splashTime = 15000;
private Handler handler;
private Runnable runnable;
private Context context;
@Override
public void onCreate(Bundle savedInstance)
{
super.onCreate(savedInstance);
setContentView(R.layout.splash);
final SplashScreen sPlashScreen = this;
handler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
try {
handler.removeCallbacks(runnable);
handler.postDelayed(runnable, _splashTime);
}
finally {
finish();
//start a new activity
//mtdCheckLicense();
Intent main = new Intent();
main.setClass(sPlashScreen, YourMainActivity.class);
startActivity(main);
handler.removeCallbacks(runnable);
}
}
};
handler.postDelayed(runnable, 2000);
}
Sarà schizzare per qualche tempo e lanciare l'attività principale. In questo codice la schermata iniziale attende 2 secondi e quindi avvia l'attività principale.
Il modo più semplice che faccio per ogni mio progetto è simile a questo:
public class SplashActivity extends Activity {
protected boolean active = true;
protected int splashTime = 1000;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
Thread splashTread = new Thread() {
@Override
public void run() {
try {
int waited = 0;
while(active && (waited < splashTime)) {
sleep(100);
if(active) {
waited += 100;
}
}
} catch(InterruptedException e) {
// do nothing
} finally {
finish();
// Start your Activity here
}
}
};
splashTread.start();
}
//...
Con le soluzioni descritte qui stai sprecando tempo, perché si fermano l'inizializzazione per 2-3seconds prima di continuare .
Preferisco aggiungere un Splash Screen Layout
in cima al mio main_activity.xml
. Rilevo il primo avvio dell'applicazione estendendo l'applicazione. Se E'il primo avvio, mostro il mio d'avvio, mentre l'interfaccia utente è costruito in sottofondo ... (Usa thread in background se il ProgressBar in ritardo!)
//Extend Application to save the value. You could also use getter/setter for this instead of Shared Preferences...
public class YourApplication extends Application {
public static final String YOUR_APP_STARTUP = "APP_FIRST_START";
@Override
public void onCreate() {
super.onCreate();
//set SharedPreference value to true
SharedPreferences mPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor = mPreferences.edit();
editor.putBoolean(YOUR_APP_STARTUP, true);
editor.apply();
...
}
Controllare per il primo avvio nel vostro MainActivity
public class YourMainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//hide actionbar and other menu which could overlay the splash screen
getActionBar().hide();
setContentView(R.layout.activity_main);
Boolean firstStart = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean(TVApplication.YOUR_APP_STARTUP, true);
if (firstStart) {
//First app start, show splash screen an hide it after 5000ms
final RelativeLayout mSplashScreen = (RelativeLayout) findViewById(R.id.splash_screen);
mSplashScreen.setVisibility(View.VISIBLE);
mSplashScreen.setAlpha(1.0f);
final FrameLayout mFrame = (FrameLayout) findViewById(R.id.frame_container);
mFrame.setAlpha(0.0f);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
Animation fadeOutAnimation = AnimationUtils.loadAnimation(getApplicationContext(),
R.anim.fade_out_animation);
fadeOutAnimation.setDuration(500);
fadeOutAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
mFrame.setAlpha(1.0f);
getActionBar().show();
}
@Override
public void onAnimationEnd(Animation animation) {
mSplashScreen.setVisibility(View.GONE);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
mSplashScreen.startAnimation(fadeOutAnimation);
}
}, 5000); //<-- time of Splash Screen shown
} else {
((RelativeLayout) findViewById(R.id.splash_screen)).setVisibility(View.GONE);
getActionBar().show();
}
Inserire lo SplashScreen in alto nel file main.xml. Preferisco lo RelativeLayout
per quello. Nell'esempio, SplashScreen è posizionato su un layout con lo Navitgation Drawer
, che adoriamo davvero, no?
//main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- The main content view -->
<FrameLayout
android:id="@+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer list -->
<ListView
android:id="@+id/slider_list"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_gravity="start"
android:background="@color/tvtv_background"
android:choiceMode="singleChoice"
android:divider="@drawable/nav_bar_divider"
android:dividerHeight="1dp"
android:listSelector="@android:color/transparent" />
</android.support.v4.widget.DrawerLayout>
<RelativeLayout
android:id="@+id/splash_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:background="@color/tvtv_white"
android:visibility="visible" >
<ImageView
android:id="@+id/splash_screen_logo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/splash_screen_text"
style="@style/TVTextBlueContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/splash_screen_logo"
android:layout_centerHorizontal="true"
android:padding="10dp"
android:text="Awesome splash shiat" />
<ProgressBar
android:id="@+id/splash_screen_loader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/splash_screen_text"
android:layout_centerHorizontal="true"
android:clickable="false"
android:indeterminate="true" />
</RelativeLayout>
</RelativeLayout>
Ciò significa che lo splash-screen sarà sempre nella gerarchia della vista, anche se non lo stai utilizzando. Se vuoi usare questo approccio, meglio usare un 'ViewStub' per quello. http://developer.android.com/reference/android/view/ViewStub.html – Jelle
Che cosa non ha funzionato in particolare per il timer? Questo approccio dovrebbe funzionare. Puoi incollare il tuo codice? –
possibile duplicato http://stackoverflow.com/questions/8642730/splash-screen-in-android-application –
Dovresti pubblicare la tua risposta se è diversa dall'altra domanda o eliminare il post se è lo stesso. – Sababado