背景
Activity遷移でよくあるパターン
Intent intent=new Intent(context,Hoge.class);
intent.putExtra("foo","bar");
startActivity(intent);
1.contextはActivityのメンバー変数なんだからわざわざ書きたくない
2.Builderパターンを使うには、おおげさすぎ
3.putExtraがあったりなかったりで、下手にstartActivityまでメソッドの中にいれるとputExtraを入れられなくなる
4.ページによっては固定でputExtraいれることがあり、たまーに入れ忘れたりする
どうにかKotinらしいコードにならないかな
ということで作ってみた
https://github.com/kamedon/KotlinIntentSample
ちょっとよくする
余談
droidkaigi2016でPageをenumで定義していて、
確かにページとタイトルを結びつけて管理していたほうが、
どのActivityがどのページだっけ?とかなくなり、
あとから見直した時にわかりやすいと思った。
https://github.com/konifar/droidkaigi2016/blob/master/app/src/main/java/io/github/droidkaigi/confsched/model/Page.java
実際のコード
Taroさんの資料を参考して、Activityの拡張関数を使うとうまいことできそう
資料だと、ActivityごとにputExtraがあったりなかったした時に面倒そう。
それも踏まえて、インテント遷移を考える
enum class Page(val nameId: Int, val page: Class<out Activity>) {
MAIN(R.string.page_main, MainActivity::class.java) {
override fun intent(context: Context): Intent {
return super.intent(context).apply { addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) }
}
},
SECOND(R.string.page_second, SecondActivity::class.java),
THIRD(R.string.page_third, ThirdActivity::class.java);
open fun intent(context: Context) = Intent(context, page)
fun name(resources: Resources) = resources.getString(nameId)
}
- pageに必ず付加するデータがある場合はintentをoverrideする。
- 例:MainのときはFLAG_ACTIVITY_CLEAR_TOPをつけている
- 後から付加するデータがある場合は、 f: (intent: Intent) -> Intentで記述。inlineなのでノーコスト!!
inline fun Activity.go(page: Page, f: (intent: Intent) -> Intent) = startActivity(f(page.intent(applicationContext)))
fun Activity.go(page: Page) = startActivity(page.intent(applicationContext))
- new Intent(context,Activity.class)のcontextはActivityのメンバー変数のため、拡張関数でいちいち打たなくてよくする
Activityでの利用の仕方
val btnSecond: Button by lazy {
findViewById(R.id.btnSecond) as Button
}
val btnThird: Button by lazy {
findViewById(R.id.btnThird) as Button
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnSecond.setOnClickListener {
//値をつける
go(Page.SECOND) {
it.putExtra("foo", "bar")
}
}
btnThird.setOnClickListener {
//ノーマルな遷移
go(Page.THIRD)
}
}
まとめ
だいぶわかりやすいなったと思うし、データをつけるときも{}で囲まれてすっきりとみえる。
finishをつけたいときにも簡単。
どうかな。。。
参考
AndroidでKotlinフル活用プログラミング #Kotlin_SansanbyTaro Nagasawa
http://sssslide.com/speakerdeck.com/ntaro/androiddekotlinhuruhuo-yong-puroguramingu-number-kotlin-sansan
Advanced Kotlin for Android #DroidKaigi #DroidKaigiB
http://sssslide.com/speakerdeck.com/ntaro/advanced-kotlin-for-android-number-droidkaigi-number-droidkaigib
konifar/droidkaigi2016
https://github.com/konifar/droidkaigi2016