slumbers

思いついたことをつらつらと

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 を取ってきてリスナーにキャストして使う。ちょっと回りくどい。


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

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)


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

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

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

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


・Window -> Preferences
Java -> Code Style -> Code Templates
・Code -> Class body を Edit

@SuppressWarnings("unused")
private static final String TAG = ${type_name}.class.getSimpleName();



これで例えば Hoge クラスを作った時に
@SuppressWarnings("unused")
private static final String TAG = Hoge.class.getSimpleName();

に置換される。
private static final String TAG = "${type_name}"
でもいいんだろうけど、もし万が一クラス名が変えた場合にめんどくさいことになりそうだから。

@SuppressWarnings("unused")

は TAG を使わなかった場合の warning を抑止。ただ TAG を使っちゃうとそれはそれで warning がでちゃうんだけど・・・・。

テンプレートも使うと便利ねということでした。

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 インスタンスの時間ずれたらどうしようとか今更心配した・・・。大丈夫だった・・・。

Eclipse で Gradle で Android する。

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

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



なにはともあれ Gradle インストール。


Mac は brew install gradle で一発。Windows はなんかめんどくさそう・・・。

環境変数
※これもいらないかも・・・?
export GRADLE_HOME=/usr/local/Cellar/gradle/1.6
export PATH=GRADLE_HOME/bin:$PATH


EclipseAndroid プロジェクトを Gradle に対応させる


File -> export
Android -> Generate Gradle build files

対象のプロジェクトを選択

build.gradle が出来ました。

Eclipse の外部ツールとして Gradle でビルドできるようにする


このアイコンから、External Tools Configurations…

こんなかんじで設定する。これだけだとただ単に端末にインストールさせるだけ。


一応はこれで Eclipse で Gradle で Android できたとした。プロジェクト配下に build ディレクトリが生成されて、build/apk に apk ファイルが置かれています。その他いろいろ掘られてる。

思ったこと

環境変数くらい引っ張ってこいよ・・・
Enviromentタブに設定した、ANDROID_HOME とかは ~/.zshrc に設定してある。それをここでももっかい設定するのだるい。
端末にインストールしたあとアプリ起動して貰いたい
Main -> Auguments に installDebug って書いてるけど、これはプロジェクトに移動してから gradle tasks を打つと一覧で出るタスクを指定している。ここの一覧にインストール後に起動するタスクが無いように思う。これは残念。(Augument に tasks って書いてもOK Console に一覧ででる。)

まあ、いろいろわからないことだらけ、徐々に慣れていこうかと。

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

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


まずは、Eclipse の Check For Updates で ADT 更新した。

アップデート後 Eclipse 再起動すると、Android SDK Manager 起動してアップデートしろとおっしゃるので従う。いろいろ更新きてた。でもこれが罠だった・・・。

Android SDK Manager 使ってアップデート後。プロジェクトが真っ赤っ赤。
ぎゃーー。

ギャーー。

どうも gen ディレクトリに何も生成されない。R.java がもちろん無いので、import の所で軒並みエラーになっていた。
Clean したり、~/.android 削除してみたり、bin ディレクトリも見えなくなってたから .classpath をいろいろいじったりしたけどダメ。ActionBarSherlock も真っ赤っ赤。Eclipse ぶっ壊れたと思って再インストール。Android SDK も新たにダウンロードしなおした。そしたら再インスールの課程の中で、Android SDK Manager に見慣れないものが。Android SDK Build-tools!?

使っていた Eclipse から Android SDK Manager を立ち上げると同じ物が表示された。どうやら Android SDK Tools を rev. 22 上げるとでてくるシロモノらしく、おまけに Android SDK Platform-tools もアップデートフラグたっとる。
2つにチェックを入れてインストール。

インストール後、Project -> Clean でエラーは全部消えてくれました。

あせった。

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