Проблема
Вы хотите создать заставку, которая появится во время загрузки приложения Android.
Решение
Вы можете создать заставку в виде объекта класса Activity
или как диалоговое окно. Поскольку его цель достигается в течение нескольких секунд, его можно удалить по истечении короткого промежутка времени или нажав кнопку на заставке.
Обсуждение
Экран заставки был изобретен в эпоху персональных компьютеров, первоначально в качестве прикрытия для медленного графического интерфейса, когда быстродействие персональных компьютеров было низким. Поставщики сохранили их для расширения популярности торговых марок. Но в мобильном мире, где самое длинное время запуска приложения, вероятно, меньше секунды, люди начинают понимать, что экраны заставок стали несколько анахроничными. Возникает вопрос: нужны ли нам все еще эти заставки? В большинстве мобильных приложений имя и логотип отображаются на панели запуска приложений и на множестве других экранов в приложении. Пришло ли время, чтобы экран заставки полностью исчез?
Ответ на этот вопрос зависит от вас и вашей организации. Для полноты рассмотрим два метода обработки экрана заставки приложения.
В первой версии используется класс Activity, предназначенный для отображения заставки. Экран заставки отображается в течение двух секунд или до тех пор, пока пользователь не нажмет клавишу меню, а затем появится основная активность приложения. Сначала мы используем поток для ожидания фиксированного количества секунд, а затем используем намерение для запуска основной активности. Единственным недостатком этого метода является то, что ваша основная активность в вашем файле androidManifest.Xml
представляет собой страницу приветствия, а не реальную основную активность. Страница приветствия приведена в примере 1.
Пример 1. Активность приветствия
public class SplashScreen extends Activity {
private long ms=0;
private long splashTime=2000;
private boolean splashActive = true;
private boolean paused=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread mythread = new Thread() {
public void run() {
try {
while (splashActive && ms < splashTime) {
if(!paused)
ms=ms+100;
sleep(100);
}
} catch(Exception e) {}
finally {
Intent intent = new Intent(SplashScreen.this, Main.class);
startActivity(intent);
}
}
};
mythread.start();
}
}
Пример 2 демонстрирует компоновку активности для вывода экрана приветствия splash.xml
.
Пример 2. Компоновка экрана приветствия
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView android:src="@drawable/background"
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ProgressBar android:id="@+id/progressBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
</ProgressBar>
</LinearLayout>
Еще одно требование — поместить атрибут android:noHistory = true
в активность splash в вашем файле AndroidManifest.xml
, чтобы она не отображалась в стеке истории, что означает, что пользователь использует кнопку Back (Назад) из основного приложения и перейдет на ожидаемый экран Заставки, а не обратно на вашу заставку (рис. 1).
Рис. 1. Заставка Android
Через две секунды эта активность приводит к следующему действию, которое является стандартной активностью “Hello, World” в качестве прокси-сервера для основной активности вашего приложения (рис. 2).
Рис. 2. “Main” Activity ("Основная" Активность)
Во второй версии (пример 3) экран заставки отображается до тех пор, пока не будет нажата клавиша меню на устройстве Android, а затем появится основная активность приложения. Для этого мы добавляем класс Java, отображающий заставку. Мы проверяем нажатие клавиши Menu
, проверяя объект класса KeyCode
и заканчивая объектом класса Activity (см. пример 3).
Пример 3. Ожидание объекта класса KeyCode
public class SplashScreen extends Activity {
private long ms=0;
private long splashTime=2000;
private boolean splashActive = true;
private boolean paused=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
super.onKeyDown(keyCode, event);
if (KeyEvent.KEYCODE_MENU == keyCode) {
Intent intent = new Intent(SplashScreen.this, Main.class);
startActivity(intent);
}
if (KeyEvent.KEYCODE_BACK == keyCode) {
finish();
}
return false;
}
}
Компоновка экрана приветствия splash.xml
остается прежней.
Как и прежде, после нажатия кнопки эта активность приводит к следующей активности, которая представляет собой основную активность.
Другим основным приемом является использование диалогового окна, начинающегося с метода onCreate()
в вашем главном методе. Этот метод имеет ряд преимуществ, в том числе более простой стек операций и тот факт, что вам не требуется дополнительная активность, которая используется только в течение первых нескольких секунд. Недостатком является то, что он требует немного больше кода, как показано в примере 4.
Пример 4. Диалоговое окно приветствия
public class SplashDialog extends Activity {
private Dialog splashDialog;
/** Вызывается при создании первой активности. /
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StateSaver data = (StateSaver) getLastNonConfigurationInstance();
if (data != null) { // "All this has happened before"
if (data.showSplashScreen ) { // And we didn't already finish
showSplashScreen();
}
setContentView(R.layout.main);
// Выполняем сборку пользовательского интерфейса,
// используя сохраненное состояние
} else {
showSplashScreen();
setContentView(R.layout.main);
// Начинаем длительную загрузку, но в отдельном потоке
}
}
Основная идея состоит в том, чтобы не только отобразить диалоговое окно приветствия при запуске приложения, но и повторно отобразить его, если вы, например, изменяете ориентацию во время работы заставки. Будьте осторожным, чтобы удалить его вовремя, если пользователь выполнит отмену или если таймер истечет во время запуска заставки.
См. также
В блоге Янга Клифтона (Ian Clifton), озаглавленном “Android Splash Screens Done Right”, предпочтение отдается диалоговому окну.