Android SplashScreen


80

Я розробляю програму, яка в основному завантажує багато даних на початку програми та відображає їх у ListActivity. Що я планую зробити, це показати заставку до завантаження даних.

Дотепер усі мої спроби були марними. Я спробував anddev.org згадані методи, але моя проблема полягає в тому, що основна Діяльність повинна починатися, але Екран Сплеску повинен бути видимим, поки я не заповню свою ListActivity. Тож коротше, я маю пройти такі кроки:

  1. Почніть мою основну діяльність.
  2. Показати заставку.
  3. Продовжуйте запускати процес у фоновому режимі.
  4. Вийдіть із заставки після завершення обробки та покажіть основний список.

Сподіваюся, ви розумієте, що це таке ....


Хто-небудь може пояснити, що навіть панель виконання не завантажується, навіть якщо я спробую створити та запустити її у функції OnCreate мого головного списку ... і відхилити після закінчення мого процесу ... навіть це не працює ... я маю на увазі, чи існує якась методологія за замовчуванням, якої мені потрібно слідувати ... як запуск індикатора прогресу в OnStart () чи щось таке ??
JaVadid

Ви пробували, що говорить прийнята відповідь у stackoverflow.com/questions/2222890/… ? EDIT: Гаразд, прийнята відповідь на
зразок

Відповіді:


89

Проблема, швидше за все, полягає у тому, що ви запускаєте заставку (якийсь діалог, такий як ProgressDialog, на мою думку) у тій самій темі, що і вся робота, що виконується. Це не дозволить оновлювати вигляд заставки, що може унеможливити його навіть відображення на екрані. Вам потрібно відобразити заставку, розпочати екземпляр AsyncTask щоб завантажити всі ваші дані, а потім приховати заставку після завершення завдання.

Отже, метод onCreate () вашого Activity просто створить ProgressDialog і покаже його. Потім створіть AsyncTask і запустіть його. Я б зробив AsyncTask внутрішнім класом вашої основної активності, щоб він міг зберігати дані, які він завантажив, до якоїсь змінної у вашому Activity і закривати ProgressDialog у своєму методі onPostExecute ().

Не знаючи, як це детальніше розробляти, а не просто показувати код, ось він:

public class MyActivity extends Activity {
    private ProgressDialog pd = null;
    private Object data = null;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Show the ProgressDialog on this thread
        this.pd = ProgressDialog.show(this, "Working..", "Downloading Data...", true, false);

        // Start a new thread that will download all the data
        new DownloadTask().execute("Any parameters my download task needs here");
    }

    private class DownloadTask extends AsyncTask<String, Void, Object> {
         protected Object doInBackground(String... args) {
             Log.i("MyApp", "Background thread starting");

             // This is where you would do all the work of downloading your data

             return "replace this with your data object";
         }

         protected void onPostExecute(Object result) {
             // Pass the result data back to the main activity
             MyActivity.this.data = result;

             if (MyActivity.this.pd != null) {
                 MyActivity.this.pd.dismiss();
             }
         }
    }    
}

Очевидно, там є деякі фрагменти, які вам потрібно заповнити, але цей код повинен запуститись і дати вам хорошу вихідну точку (пробачте, якщо є помилка коду, я не маю доступу до Android SDK, оскільки я набираю це в даний час).

Ще кілька хороших читань на тему AsyncTasks в Android можна знайти тут і тут .


Що ви маєте на увазі під поверненням "замінити об'єктом даних"? У мене є дві функції, які я хочу завантажити в асинктаск, як ви сказали, але я не знаю, що я повинен повернути. Я намагався повернути значення null, але програма аварійно завершує роботу.
Нік

AsyncTask <String, Void, Object>, де Object представляє тип даних, який потрібно повернути. Див. Розділ "Загальні типи AsyncTask" тут: developer.android.com/reference/android/os/AsyncTask.html
Позначити B

Я знаю, що це старе, але я спробував це реалізувати, і ProgressDialog(у моєму випадку звичайний діалог, який завантажує макет) ніколи не відображається. Я бачу тільки , якщо я закомментировать .dismiss()в onPostExecute. Перший екран, який я бачу, все ще є MyActivityтемою. Після цього йде прямо до R.layout.main.
Kevin_TA

@Kevin_TA, якщо .dismiss () призводить до того, що він не відображається, ваша AsyncTask негайно закінчується. Метод, який я описав, - це відображення заставки, що відображається під час запуску деякого запущеного запуску.
Mark B

@mbaird це закінчується не відразу. Я справді маю фоновий процес, який триває 2-3 секунди. Хоча з якихось причин ніщо в інтерфейсі не оновлюється до закінчення асинхронізації, таким чином перемагаючи мету.
Kevin_TA

61

лише для довідки, це найкращий спосіб, який я знайшов, щоб зробити заставку: http://android-developers.blogspot.de/2009/03/window-backgrounds-ui-speed.html

Я шукав це досить довго, з андроїд-документів ... якщо ви хочете уникнути цих чорних екранів, вам потрібно створити тему за допомогою windowBackground так:

<resources>
    <style name="Theme.Shelves" parent="android:Theme">
        <item name="android:windowBackground">@drawable/background_shelf</item>
        <item name="android:windowNoTitle">true</item>
    </style>
</resources>

І встановіть цю тему як тему для своєї основної діяльності ... TADA, заставний екран з першої секунди.

Якщо вам потрібен складний фон, а не просто зображення, яке буде розтягнуто для заповнення, ви можете використовувати Drawables, ось приклад списку шарів, який буде тримати логотип у центрі з чорним фоном:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item android:drawable="@color/black">
    </item>
    <item>
        <bitmap
            android:gravity="center"
            android:src="@drawable/logo"
            android:tileMode="disabled" >
        </bitmap>
    </item>
</layer-list>

1
це посилання мертве, але вміст сторінки та вихідний код доступні на archive.org: web.archive.org/web/20101113015720/http://developer.android.com/…
Spoonface

Чи є спосіб використовувати layout.xml замість того, щоб малювати для android: windowBackground? Під час спроби я отримую збій, але мені цікаво, чи є обхідне рішення.
Kevin_TA

@Kevin_TA ні, немає. АЛЕ ви можете використовувати Drawables, тому, якщо ви хочете мати логотип посередині екрана, тоді ви повинні використовувати список шарів, який можна малювати, і використовувати гравітацію для розміщення ваших зображень. Відповідь оновлю на прикладі.
Raanan

1
Рішення @Ranaan Theme працює для мене, але як мені підключити список шарів до теми?
deko

2
@deko item name = "android: windowBackground" може бути або фіксованим кольором, або зображенням, або файлом у форматі XML, як список шарів, розміщений у вашій папці res / drawable. Ви можете прочитати про Drawables тут: developer.android.com/guide/topics/resources/…
Раанан,

1

Приклад заставки:

public class MainActivity extends Activity {
    private ImageView splashImageView;
    boolean splashloading = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        splashImageView = new ImageView(this);
        splashImageView.setScaleType(ScaleType.FIT_XY);
        splashImageView.setImageResource(R.drawable.ic_launcher);
        setContentView(splashImageView);
        splashloading = true;
        Handler h = new Handler();
        h.postDelayed(new Runnable() {
            public void run() {
                splashloading = false;
                setContentView(R.layout.activity_main);
            }

        }, 3000);

    }

}

1
  1. Почніть мою основну діяльність.
  2. Показати заставку.
  3. Продовжуйте запускати процес у фоновому режимі.
  4. Вийдіть із заставки після завершення обробки та покажіть основний список.

Я спробував таким чином, але проблема в тому; він покаже основну активність перед початком активності заставки.

Я зробив це так:

  1. Запустіть екран заставки
  2. Коли процес завершиться, розпочніть "основну діяльність"
  3. Не забудьте обробити кнопку "Назад", тому вона повинна бути закрита. Програма буде натиснута в основному режимі. В іншому випадку повернеться на заставку (цикл)

Моя проблема полягає в тому, як вимкнути "показувати меню активності екрану заставки", натискаючи кнопку меню.

Редагувати:

Вимкнути меню шоу:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // getMenuInflater().inflate(R.menu.activity_main, menu);
    return false;
}

@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {       
    // return super.onMenuItemSelected(featureId, item);
    return false;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.