7月 18
インターネットアクセスには時間がかかる場合が多いので、画面遷移中にプログレスダイアログを表示させたい場合があります。今日はそんな時に使用できる Tips です。

ただ WebView の画面遷移中にプログレスダイアログを出すだけでは面白くないのでダイアログにはカスタムビューを使用します。また、進捗を分かり易く表現するためにアニメーションを使用してみましょう。

サンプルアプリ

今日のサンプルアプリではページの切替時に以下のような進捗を示すダイアログを表示させます。ちょっと見づらいですが画面中央に透過の背景を持つダイアログが表示されています。中央のインディケータはアニメーションしています。

device-1.png

ダイアログの表示/非表示のタイミング

ダイアログを表示/非表示させるタイミングには WebView の持つ WebViewClient の onPageStarted, onPageFinished を使います。標準の振る舞いを変えるために WebViewClient を継承したクラスを作成したうえで onPageStarted, onPageFinished をオーバライドします。(onPageStarted でダイアログの生成と表示、onPageFinished でダイアログの非表示と破棄)ここで作成したクラスを WebView の setWebViewClient に設定します。

        WebView wv = (WebView)findViewById(R.id.webview);
        wv.setWebViewClient(new MyWebViewClient());

    (略)

    private class MyWebViewClient extends WebViewClient {
        private AnimationDrawable animation;
       
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            Log.d("debug", "onPageStarted: " + url);
            if (dialog != null) {
                dialog.dismiss();
            }
            dialog = new Dialog(Main.this, R.style.MyProgressTheme);
            dialog.setContentView(R.layout.my_progress_dialog);
            dialog.show();

            // アニメーションの動作
            ImageView iv = (ImageView)dialog.findViewById(R.id.image);
            iv.setBackgroundResource(R.drawable.ic_spinner);
            animation = (AnimationDrawable)iv.getBackground();
            startAnimation();
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            Log.d("debug", "onPageFinished: " + url);
            stopAnimation();
            dialog.dismiss();
            dialog = null;
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            Log.d("debug", "onReceivedError: " + failingUrl + " (code: " + errorCode + ")");
            stopAnimation();
            dialog.dismiss();
            dialog = null;
        }
       
    (略)
    }

Main.java

カスタムダイアログ

ダイアログのカスタマイズは、ダイアログ生成時にテーマを指定することで簡単に行えます。(手を加えるファイルが多いので一見複雑ですが慣れれば簡単です。)

            dialog = new Dialog(Main.this, R.style.MyProgressTheme);
            dialog.setContentView(R.layout.my_progress_dialog);

(layout/my_progress_dialog.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   >
    <ImageView
       android:id="@+id/image"
       android:layout_width="90dp"
       android:layout_height="90dp"
       android:background="@drawable/ic_spinner"
       android:layout_centerInParent="true"
       />
</RelativeLayout>

(values/themes.xml)

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="MyProgressTheme" parent="android:style/Theme.Dialog">
        <item name="android:windowBackground">@drawable/my_progress_frame</item>
        <item name="android:windowNoTitle">true</item>
    </style>
</resources>

(drawable/my_progress_frame.xml)

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#80808080"/>
    <corners android:radius="20dp"/>
    <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />
    <stroke android:width="0dp" android:color="#a0808080" />
</shape>

アニメーション

イメージをアニメーションさせるには AnimationDrawable を使用します。アニメーションは何もしなければ始まりません。onPageStarted でダイアログを表示させた後でアニメーションを開始させます。終了時には onPageFinished, onReceivedError でアニメーションを停止させます。

(drawable/ic_spinner.xml)

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
   android:oneshot="false" >
    <item android:drawable="@drawable/ic_spinner1" android:duration="60" />
    <item android:drawable="@drawable/ic_spinner2" android:duration="60" />
    <item android:drawable="@drawable/ic_spinner3" android:duration="60" />
    <item android:drawable="@drawable/ic_spinner4" android:duration="60" />
    <item android:drawable="@drawable/ic_spinner5" android:duration="60" />
    <item android:drawable="@drawable/ic_spinner6" android:duration="60" />
    <item android:drawable="@drawable/ic_spinner7" android:duration="60" />
    <item android:drawable="@drawable/ic_spinner8" android:duration="60" />
</animation-list>

(Main.java)

            // アニメーションの動作
            ImageView iv = (ImageView)dialog.findViewById(R.id.image);
            iv.setBackgroundResource(R.drawable.ic_spinner);
            animation = (AnimationDrawable)iv.getBackground();
            startAnimation();

      (略)

        private void startAnimation() {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    animation.start();
                }
            });
        }

サンプルコード

サンプルアプリのソースコードは Google Code で公開しています。完全なサンプルコードを参照したい場合はそちらをどうぞ。



Posted by sak+

Comments are closed.

preload preload preload