Androidスプラッシュスクリーン


80

基本的にアプリケーション自体の起動時に大量のデータをダウンロードしてListActivityに表示するアプリケーションを開発しています。私がやろうとしているのは、データがロードされるまでスプラッシュ画面を表示することです。

今まで私の試みはすべて無駄でした。anddev.orgで言及されているメソッドを試しましたが、問題は、メインアクティビティが開始されるはずなのに、ListActivityにデータを入力するまでスプラッシュ画面が表示されることです。つまり、次の手順を実行する必要があります。

  1. 私の主な活動を開始します。
  2. スプラッシュ画面を表示します。
  3. プロセスをバックグラウンドで実行し続けます。
  4. 処理が完了したらスプラッシュ画面を終了し、メインリストを表示します。

それがどのようなものか理解していただければ幸いです。


メインリストのOnCreate関数でプログレスバーを作成して開始しようとしても、プログレスバーが読み込まれていないことを誰かが説明できますか...プロセスが終了した後にそれを閉じます...これでも機能しません... i OnStart()でプログレスバーを開始するなど、従う必要のあるデフォルトの方法はありますか?
JaVadid 2009

stackoverflow.com/questions/2222890/…で受け入れられた答えが言うことを試しましたか?編集:
わかり

回答:


89

問題は、実行されているすべての作業と同じスレッドでスプラッシュ画面(ProgressDialogなどのある種のダイアログ)を実行している可能性があります。これにより、スプラッシュ画面のビューが更新されなくなり、画面に表示されないようにすることができます。スプラッシュ画面を表示し、AsyncTaskのインスタンスを開始してすべてのデータをダウンロードし、タスクが完了したらスプラッシュ画面を非表示にする必要があります。

したがって、アクティビティのonCreate()メソッドは、ProgressDialogを作成して表示するだけです。次に、AsyncTaskを作成して開始します。AsyncTaskをメインアクティビティの内部クラスにして、ダウンロードしたデータをアクティビティの変数に格納し、onPostExecute()メソッドでProgressDialogを閉じることができるようにします。

コードを表示せずにもう詳しく説明する方法がわからないので、ここにあります:

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();
             }
         }
    }    
}

明らかに、そこに入力する必要のある部分がいくつかありますが、このコードは実行され、良い出発点になるはずです(コードエラーがある場合はご容赦ください。これを入力しているため、AndroidSDKにアクセスできません。現在)。

AndroidのAsyncTasksに関するいくつかのより良い読み物は、ここここにあります


「データオブジェクトに置き換える」とはどういう意味ですか?あなたが言ったように、非同期タスクにロードしたい2つの関数がありますが、何を返すのかわかりません。nullを返そうとしましたが、アプリがクラッシュします。
ニック

AsyncTask <String、Void、Object>ここで、Objectは、返すデータ型を表します。こちらの「AsyncTaskのジェネリック型」セクションを参照してください:developer.android.com/reference/android/os/AsyncTask.html
Mark B

これは古いことですが、これを実装しようとしましたが、ProgressDialog(私の場合はレイアウトをロードする通常のダイアログ)が表示されません。でコメントアウトした場合にのみ表示さ.dismiss()れますonPostExecute。私が見る最初の画面はまだMyActivityテーマです。その後、それはまっすぐに行きR.layout.mainます。
kevin_TA 2014年

@Kevin_TA .dismiss()が原因で表示されない場合、AsyncTaskはすぐに終了します。私が概説した方法は、長時間実行されている起動タスクの実行中に表示されるスプラッシュ画面を表示するためのものです。
マークB

@mbairdすぐには終了しません。確かに、完了するまでに2〜3秒かかるバックグラウンドプロセスがあります。ただし、何らかの理由で、非同期が実行されるまでUIの何も更新されないため、目的が無効になります。
kevin_TA 2014年

61

参考までに、これはスプラッシュ画面を作成するために私が見つけた最良の方法です:http//android-developers.blogspot.de/2009/03/window-backgrounds-ui-speed.html

私はかなり長い間、androids docsからこれを探していました。これらの黒い画面を避けたい場合は、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、最初の1秒からのスプラッシュスクリーン。

塗りつぶすために引き伸ばされる画像だけでなく、複雑な背景が必要な場合は、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

android:windowBackgroundのドローアブルの代わりにlayout.xmlを使用する方法はありますか?そうしようとするとクラッシュしますが、回避策があるのではないかと思います。
kevin_TA 2014年

@Kevin_TAいいえありません。ただし、Drawableを使用できるため、画面の中央にロゴを表示する場合は、レイヤーリストのDrawableを使用し、重力を使用して画像を配置する必要があります。例を挙げて回答を更新します。
Raanan 2014年

1
@Ranaanテーマソリューションは私には機能しますが、レイヤーリストをテーマに接続するにはどうすればよいですか?
deko 2014

2
@deko item name = "android:windowBackground"は、固定の色または画像、あるいはres / drawableフォルダーに配置されたlayer-listのようなxmlドローアブルのいずれかです。あなたはここにドローアブルについて読むことができます。developer.android.com/guide/topics/resources/...
Raanan

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;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.