2011年6月2日木曜日

Android 進捗表示の方法あれこれ

今までタスクの進捗を表示するときProgressDialogで"くるくるまわってる"やつを一択で使ってたけど、他にもタイトルバー上に表示したり、進捗率を表示させたりと色々あるようなので簡単にメモ。

タイトルバー上に表示するには下記の設定が必要。setContentViewよりも先に行う。
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
    requestWindowFeature(Window.FEATURE_PROGRESS);
上がKURU KURUの設定で、下が進捗率の設定。indeterminateは予測できないとか正確ではないって意味。

ダイアログで進捗率を表示するにはProgressDialog.setProgressStyleで設定
    dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
上がKURU KURUで、下が進捗率。デフォルトはSTYLE_SPINNERなので、くるくるのときは設定は不要。
詳しくはProgressDialog | Android Developers

ま、一応サンプル。
public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        requestWindowFeature(Window.FEATURE_PROGRESS);

        setContentView(R.layout.main);

        Button mIndeterminateProgressTitle = (Button) findViewById(R.id.indeterminate_progress_title);
        Button mProgressTitle = (Button) findViewById(R.id.progress_title);
        Button mIndeterminateProgressDialog = (Button) findViewById(R.id.indeterminate_progress_dialog);
        Button mProgressDialog = (Button) findViewById(R.id.progress_dialog);
        mIndeterminateProgressTitle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                new IndeterminateProgressTitleTask().execute();
            }
        });
        mProgressTitle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                new ProgressTitleTask().execute();
            }
        });
        mIndeterminateProgressDialog.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                new IndeterminateProgressDialogTask().execute();
            }
        });
        mProgressDialog.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                new ProgressDialogTask().execute();
            }
        });
        setProgress(10000);
    }

    public class IndeterminateProgressTitleTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            setProgressBarIndeterminateVisibility(true);
        }
        @Override
        protected Void doInBackground(Void... args) {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void result) {
            setProgressBarIndeterminateVisibility(false);
        }
    }

    public class ProgressTitleTask extends AsyncTask<Void, Integer, Void> {
        @Override
        protected void onPreExecute() {
            setProgress(0);
            setProgressBarVisibility(true);
        }
        @Override
        protected Void doInBackground(Void... args) {
            try {
                for (int i = 0; i <= 10; i++) {
                    publishProgress(i);
                    Thread.sleep(i * 100);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }
        @Override
        protected void onProgressUpdate(Integer... values) {
            setProgress(values[0] * 1000);
        }
        @Override
        protected void onPostExecute(Void result) {
            setProgressBarVisibility(false);
        }
    }

    public class IndeterminateProgressDialogTask extends AsyncTask<Void, Void, Void> {
        ProgressDialog dialog;
        @Override
        protected void onPreExecute() {
            dialog = new ProgressDialog(MainActivity.this);
            dialog.setMessage("Now loading...SKY!!");
            dialog.show();
        }
        @Override
        protected Void doInBackground(Void... args) {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void result) {
            dialog.dismiss();
        }
    }

    public class ProgressDialogTask extends AsyncTask<Void, Integer, Void> {
        ProgressDialog dialog;
        @Override
        protected void onPreExecute() {
            dialog = new ProgressDialog(MainActivity.this);
            dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            dialog.setMax(10);
            dialog.setIndeterminate(false);
            dialog.show();
        }
        @Override
        protected Void doInBackground(Void... args) {
            try {
                for (int i = 0; i <= 10; i++) {
                    publishProgress(i);
                    Thread.sleep(i * 100);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }
        @Override
        protected void onProgressUpdate(Integer... values) {
            dialog.setProgress(values[0]);
        }
        @Override
        protected void onPostExecute(Void result) {
            dialog.dismiss();
        }
    }
}
onCreateの終わりでsetProgressしてるのは、最初にタイトルバーにくるくるのを表示しようと押したときに進捗バーがうっすら表示されるのを防ぎたいため。グルグルだけ表示したい(FEATURE_PROGRESSを設定しない)ならば必要はない。

ダイアログにするかタイトルバー上に表示するかはどう使い分ければいいのかな?好みかな。作戦立てるか。