2013/11/08

DialogFragment のイベントを Activity とか Fragment に伝えたい。

削除しますか?「はい/いいえ」の確認ダイアログ出して、「はい」したらもとの画面からも消えてるみたいな。ダイアログのイベントを元々の画面伝えたい。そんな感じのよくある話。

DialogFragment になにか渡したいときは Fragment の特徴である DialogFragment#setArguments() で渡さないといけない。でもリスナー渡したいときは一筋縄ではいかない。DialogFragment#setOnDoSomethingListener() なんかを生やしても大人の事情でダメ。ここでこうやってみる。

まずはなんにせよ Listener を作る。

こんな感じ。

Activity に通知する場合。


Activity にリスナーを implements するの忘れない。Dialog 側は onAttach(Activity activity) をオーバーライドする。ライフサイクルに組み込まれてるこのメソッドでは Activity が渡されるので、そのアクティビティが Listener を implements してるかチェックできる。なので DialogFragment#setArguments() で渡さなくてもいい。

こんな感じ。あとは必要なところでthis.mOnDialogButtonClickListenerのメソッド使えばいい。

Fragment に通知する場合。


DialogFragment にいつもの newInstance() を生やす。ここで引数に Fragment をとるようにして、DialogFragment#setTargetFragment() を使って Fragment を保持。必要なときに DialogFragment#getTargetFragment() から Fragment を取ってきてリスナーにキャストして使う。ちょっと回りくどい。


こんな感じでいいんじゃまいか。

2013/11/06

DialogFragment#dismiss() で NullPointerException がたまにでる。

「たまにでる」ここぽいんと。

ローディングのくるくるダイアログとか DialogFragment とかって出すことは、まあよくあると思う。そんな感じで出してたら NullPointerException でた。
こんな感じのとこ。



いやいや、null じゃなければって言ってるでしょ?どうも DialogFragment の中で何かが null っぽい(例外メッセージ忘れた)なので、こう変えた。



TAG を指定して生成、消すときも TAG 指定で取得、fragment が帰ってくるから一応 null チェックとそいつが DialogFragment かどうかを見て、dismiss() 呼び出す。これで一応 NullPointerException はなくなりました。ここらへんどうなんだろうかっていうのはある。ドキュメント見てもshow() の例は書いてるけど dismiss() の例もないものね。

追記


12-03 17:57:12.331: E/AndroidRuntime(5279): java.lang.NullPointerException
12-03 17:57:12.331: E/AndroidRuntime(5279): at android.support.v4.app.DialogFragment.dismissInternal(DialogFragment.java:184)
12-03 17:57:12.331: E/AndroidRuntime(5279): at android.support.v4.app.DialogFragment.dismiss(DialogFragment.java:155)


こんなかんじの例外でした。

2013/07/21

Android でクラスを作るときに TAG も一緒につくる。

Log.d(TAG, "hogehoge")
とか何かと物入りな TAG という代物。

クラスを作成するたびに
private static final String TAG = "hoge";
とかやっていたけど、まあめんどいし忘れるし。
うまいことできんかと思ったらテンプレート機能が Eclipse さんには備わっておる。

2013/06/04

Java の Calendar は Singleton ではなくて Factory Method。

カレンダーを取得する際はCalendar.getInstance() でとる。このgetInstalnce()だけで、勝手にシングルトンだと思っていた。実際は Factory Method パターン でした。

ソースコードを見ると
Calendar#getInstance() -> Calendar#createCalendar(TimeZone zone, Locale aLocale) で言語、国なんかを判別して
  • new sun.util.BuddhistCalendar(zone, aLocale);
  • new JapaneseImperialCalendar(zone, aLocale);
  • new GregorianCalendar(zone, aLocale);
を new してインスタンス生成して返してる。

シングルトンだと思っていたから、 Calendar#add() とかして、アプリで使う Calendar インスタンスの時間ずれたらどうしようとか今更心配した・・・。大丈夫だった・・・。

2013/05/19

Eclipse で Gradle で Android する。

なんか Maven でこの前同じようなの書いてた気がするが、Maven は諦めた。XML の設定が慣れない・・・・。 Gradle は Groovy らしい。Groovy よくわかってない。

どうも Android のビルドツールは Gradle になるようだ。Android Studio のビルドツールは Gradle。ant が何かもよくわかってないのに!そして ActionBarSherlock も Gradle に対応したらしいし、ADT 22 から Gradle プロジェクトにエクスポートもできるようですしとりあえず触ってみる。

2013/05/16

Eclipse ADT 22 のバージョンアップでは Android SDK Manager のアップデートは 2 回する。

Android Studio が発表されたり、そんななか ADT もバージョンアップして、おもむろにカジュアルにバージョンアップした。そしたらエラーだらけで大変なことに。

2013/05/03

Mac で JAVA_HOME 環境変数を設定する。

zsh にを使っていて JAVA_HOME 環境変数を設定する必要がある。

~/.zshrc

◯ export JAVA_HOME=$(/usr/libexec/java_home)

× export JAVA_HOME=/usr/libexec/java_home

$() で囲まないと以下のように怒られる。
Error: JAVA_HOME is not defined correctly.
We cannot execute /usr/libexec/java_home/bin/java
実行結果を展開してるのかな?

シンボリックリンクになっているようだ
ls -al /usr/libexec/java_home
lrwxr-xr-x 1 root wheel 79 4 27 21:16 /usr/libexec/java_home -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java_home