Android、Java、Web系、Linux、マラソン等の備忘録

2013/10/28

項目にアイコンを表示するAlertDialog.Builderのダイアログ

0 件のコメント
Androidアプリ中に、AlertDialog.Builderを使って、いろいろな場面でダイアログを表示させてると、処理をまとめたくなるわけですが、あと、アイコンなんかも表示したいなと、


ググってたらスマートなやり方(下記Tom Esterez氏の回答)がありました。
・android - how to add icon in alert dialog before each item? - Stack Overflow
http://stackoverflow.com/questions/3920640/how-to-add-icon-in-alert-dialog-before-each-item
itemsの中身を代えてやれば、簡単に項目の追加削除が行えますね。使い回せそうなクラスが割りと完結に書けたので、アイコンなしバージョンも合せてメモしておきます。

アイコンなしのダイアログ

冒頭のスマートなやり方はここではほぼ関係ありません。CharSequenceの配列に定義した文字列を表示するダイアログです。
import android.util.Log;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;

public class ItemDialogUtility {

    public interface Listener {
        public void onClickItem(int item);
    }

    /**
     * アイコンなしダイアログ
     * @param context
     * @param listener
     * @param title
     * @param items
     */
    public static void show(Context context, final Listener listener,
            String title, CharSequence[] items) {

        AlertDialog.Builder dialog = new AlertDialog.Builder(context);
        dialog.setTitle(title);
        dialog.setItems(items, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int item) {

                Log.v("ItemDialogUtility", item + "番目が選択されました");
                // ダイアログ閉じる
                dialog.dismiss();
                // リスナーのメソッドを実行
                listener.onClickItem(item);
            }
        });
        dialog.show();
    }
}

ダイアログの任意の項目がクリックされた処理は呼び出し元で行うよう、onClickItemというインタフェースを定義しています。そのため、呼び出し元側ではそのメソッドを定義し、定義されているインスタンスをパラメータに渡してやる必要があります。showメソッドのパラメータに従って値を渡せばダイアログが表示されるわけですが、これをActivityから呼び出すと以下のようになります。
public class DialogTestActivity extends Activity
implements ItemDialogUtility.Listener{

    private static final CharSequence[] items = {"編集","削除"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dialog_test);

        ItemDialogUtility.show(this, this, "コメント", items);
    }

    @Override
    public void onClickItem(int item) {
        // .. ダイアログの項目クリック後の処理
    }
}

この場合インターフェースのメソッドは、DialogTestActivityにimplementsしてonClickItemメソッドを定義しているので、第二引数にthisとして渡しています。

実行するとこのように↓


アイコン付きダイアログ

アイコン付きは冒頭のスマートなやり方を適用しています。

import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;

public class ItemDialogUtility {

    public interface Listener {
        public void onClickItem(int item);
    }

    public static class ListItem{
        public final String text;
        public final int icon;
        public ListItem(String text, Integer icon) {
            this.text = text;
            this.icon = icon;
        }
        @Override
        public String toString() {
            return text;
        }
    }

    /**
     * アイコン付きダイアログ
     * @param context
     * @param listener
     * @param title
     * @param items
     */
    public static void show(Context context, final Listener listener,
            String title, ListItem[] items) {

        ListAdapter adapter = new ListAdapter(context, items);

        AlertDialog.Builder dialog = new AlertDialog.Builder(context);
        dialog.setTitle(title);
        dialog.setAdapter(adapter, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int item) {

                Log.v("ItemDialogUtility", item + "番目が選択されました");
                // ダイアログ閉じる
                dialog.dismiss();
                // リスナーのメソッドを実行
                listener.onClickItem(item);
            }
        });

        dialog.show();
    }

    /**
     * アイコン付き用リストのアダプター
     */
    public static class ListAdapter extends ArrayAdapter<ListItem> {

        private Context mContext = null;

        public ListAdapter(Context context, ListItem[] itmes) {
            super(context, android.R.layout.select_dialog_item,
                    android.R.id.text1, itmes);
            mContext = context;
        }

        public View getView(int position, View convertView, ViewGroup parent) {

            ListItem item = this.getItem(position);

            //User super class to create the View
            View v = super.getView(position, convertView, parent);
            TextView tv = (TextView)v.findViewById(android.R.id.text1);

            //Put the image on the TextView
            tv.setCompoundDrawablesWithIntrinsicBounds(item.icon, 0, 0, 0);

            //Add margin between image and text (support various screen densities)
            int dp5 = (int) (5 *
                    mContext.getResources().getDisplayMetrics().density + 0.5f);
            tv.setCompoundDrawablePadding(dp5);

            return v;
        }
    }
}

呼び出し元側としてはCharSequenceの配列としていた部分を、ListItemクラスのインスタンスの配列として渡してやるのが違うだけです。

public class DialogTestActivity extends Activity
implements ItemDialogUtility.Listener{

    private static final ItemDialogUtility.ListItem[] items = {
        new ItemDialogUtility.ListItem("編集", android.R.drawable.ic_menu_edit),
        new ItemDialogUtility.ListItem("削除", android.R.drawable.ic_menu_delete),
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dialog_test);

        ItemDialogUtility.show(this, this, "コメント", items);
    }

    @Override
    public void onClickItem(int item) {
        // .. ダイアログの項目クリック後の処理
    }
}

実行するとこのように↓

別々に書きましたが、アイコンなし、アイコン付きダイアログはItemDialogUtility内に一緒に書いてやれば、いろいろ使い回せそうです。こうやっておけば、呼び出し元でAlertDialog.Builderを特に意識してなくても、表示させられるのではないでしょうか。

PR

0 件のコメント :

コメントを投稿