スキップしてメイン コンテンツに移動

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

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

コメント

このブログの人気の投稿

Javaでprivateなfieldやmethodにアクセスする

JUnitでテストしてると、privateなフィールドにアクセスして、値を参照したりセットしたりしたくなるわけですが、よく使うのでメモしておきます。 例えば、次のような対象のクラスがあるとします。 public class ParentClass { private String hoge = "ParentClass!!"; public void dispMsg() { System.out.println("dispMsg:" + hoge); } private void privateDispMsg(String msg) { System.out.println("dispMsg:" + msg); } }

GolangでWindows GUIアプリケーション

GUIアプリ作成の前提 社内ツールとしてexeで配布 開発環境はGoLandを使う 社内ツールとしてexeを配布ということであれば、Visual StudioでC#による開発だと思います。しかしながら、Go言語を習得したいのと、GoLandの補完機能が便利で、Android Studio使っていたこともあり、とっつきやすいという点からGo縛りでGUIアプリケーションを考えたいと思います。 lxn/walk Windows application library kit for Go. Windows向けしか考えていないので、まずこのライブラリなのですが、ボタンやコンボボックスが思ったように並ばなかったり、手軽にイメージボタンを配置したりなど、簡単にレイアウトを変更できない課題に直面しました。レイアウト作成だけで時間を取られてしまいます。そう言えば、Androidアプリ開発のときは、XMLでデザイン部分を切り離してたのを思い出して、今回の調査の運びとなりました。 fyne-io/fyne Cross platform native GUIs designed for Go based on Material Design. Supports: Linux, macOS, Windows, BSD, iOS and Android. walkと比べると、クロスプラットフォームで作成できるのですが、こちらもコードの中にデザインを書いていく形でした。 therecipe/qt therecipe/qt allows you to write Qt applications entirely in Go or JavaScript. Qt Creatorなるものがあるようで、デザイン部分を切り離せる印象はあるものの、最新のPCでもビルドに時間がかかるようで、学習コストもかかるという記事を見かけて断念しました。 どうしたものかとツイートしましたら、下記のようにご助言をいただいた。 同じ課題に対し色々試した結果、PWAのフルキャッシュドに落ち着いた。中身はGo+WASMで。 https://t.co/e60whDTV16 — のぼのぼ📡 (@nobonobo) July 21, 2020 PWA 早速調べてみました。Googleが進めているプロジェクトで、ネイティブアプリのよ

Eclipseの高速化メモ

Eclipseが重いと一言に言っても、いろいろな工程での話があると思いますが、過去記事のなども含めてこの記事にピックアップしておきたいと思います。以下はWindows環境での話です。