2013年5月16日木曜日

[Android] AlertDialog風なDialogFragmentを作成する

Fragmentが導入されてから、Dialog系(showDialog()とか)のAPIが非推奨になり、半ばDialogFragmentを強要されてますが、ちょっと使うのが面倒くさい。
簡単な文字とかリストを表示するだけならAlertDailogみたいな感じで使いたい!と思ったので作りました。

需要ないだろうなーと思って適当にローカルで使ってましたが、調べてみたら結構あったのでちゃんとしたの作ってみました。

ちょっと大きくなったのでソースはGithubに置きます。
https://github.com/lilylight/AlertDialogFragment

使用例
package jp.lilylight.alertdialogfragment.sample;

import jp.lilylight.alertdialogfragment.AlertDialogFragment;
import jp.lilylight.alertdialogfragment.DialogFragmentInterface.OnClickListener;
import jp.lilylight.alertdialogfragment.DialogFragmentInterface.ListAdapterDelegate;
import jp.lilylight.alertdialogfragment.R;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.Toast;

public class MainActivity extends FragmentActivity implements OnClickListener, ListAdapterDelegate {

    private static final int ID_DIALOG_ALERT = 1;
    private static final String[] ITEMS = new String[] {
            "アイテム1",
            "アイテム2",
            "アイテム3",
            "アイテム4",
            "アイテム5",
    };

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

        findViewById(android.R.id.button1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showAlertDialog();
            }
        });
    }

    @Override
    public void onClick(int id, DialogInterface dialog, int which) {
        switch (id) {
            case ID_DIALOG_ALERT:
                Toast.makeText(this, ITEMS[which], Toast.LENGTH_SHORT).show();
                break;

            default:
                break;
        }
    }

    @Override
    public ListAdapter getAdapter(int id) {
        return new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, ITEMS);
    }

    private void showAlertDialog() {
        new AlertDialogFragment.Builder(this)
//              .setTargetFragment(this) Fragmentの場合
                .setId(ID_DIALOG_ALERT)
                .setIcon(R.drawable.ic_launcher)
                .setTitle("サンプル")
                .setAdapter(this, this)
                .setNeutralButton(android.R.string.cancel, null)
                .create()
                .show(getSupportFragmentManager());
    }
}
制約としてAlertDialogと違う点は

  • Bundle型に格納できない引数は~Delegateの戻り値で渡す
  • ~Listenerは必ずFragmentActivityかFragmentに実装する

Fragmentの性質上難しいけど割と嫌な制約...
匿名クラス使いたい(バンバン

全部試したわけじゃないのでバグってるかもしれません。その時はpullなり焼くなりしてください。