Slide 1

Slide 1 text

AndroidでKotlin フル活用プログラミング 2016-01-15 AndroidでKotlin勉強会 @ Sansan 長澤 太郎 @ngsw_taro

Slide 2

Slide 2 text

自己紹介 ● 長澤 太郎 @ngsw_taro ● 仕事ではAndroidメイン、Java, Scala, Railsなど ● Kotlinエバンジェリスト(自称) ○ 講演や執筆などの実績多数 ● 27歳、蟹座、ビール大好き

Slide 3

Slide 3 text

私のブログ

Slide 4

Slide 4 text

アプリカティブなんとかみたいなやつ val minus = { a: Int -> { b: Int -> a - b } } fun T.bind(f: ((T)->R)?): R? = f?.invoke(this) y?.bind(x?.bind(minus)) fun ((T)->R).apply(n: T?): R? = n?.bind(this) val sub: Int? = minus.apply(x)?.apply(y) http://taro.hatenablog.jp/entry/2014/04/06/144811

Slide 6

Slide 6 text

Extensionで なんでもするマン

Slide 7

Slide 7 text

AndroidでKotlin Extensionプログラミング 2016-01-15 AndroidでKotlin勉強会 @ Sansan 長澤 太郎 @ngsw_taro

Slide 8

Slide 8 text

RxLifecycle面倒

Slide 9

Slide 9 text

RxLifecycleを使う // in RxAppCompatActivity apiAccesss() .compose(bindToLifecycle()) .subscribe { ... } 省略できないっぽい

Slide 10

Slide 10 text

こうしたい: 拡張関数使えばできそう // in RxAppCompatActivity apiAccesss() .bindToLifecycle() .subscribe { ... }

Slide 11

Slide 11 text

こういうの作る // in RxAppCompatActivity fun Observable.bindToLifecycle() = compose(self.bindToLifecycle()) いい感じ! 共通部品化したい

Slide 12

Slide 12 text

こういう提案 interface RxLifecycleFeature: ActivityLifecycleProvider { fun Observable.bindToLifecycle() = compose([email protected]()) }

Slide 13

Slide 13 text

使用側のアクティビティ class MyActivity: RxAppCompatActivity(), RxLifecycleFeature { fun go() { apiAccess() .bindToLifecycle() .subscribe {...} } }

Slide 14

Slide 14 text

明示的Activity起動の問題

Slide 15

Slide 15 text

よくあるやつ: 遷移先 class TargetActivity: Activity() { companion object { fun intent(c: Context, data: String) = Intent(c, TargetActivity::class.java) .putExtra(“data”, data) } }

Slide 16

Slide 16 text

よくあるやつ: 遷移元 class SourceActivity: Activity() { fun go() { val data = “hogefuga” startActivity(TargetActivity.intent(this, data)) } }

Slide 17

Slide 17 text

よくあるやつ: 遷移元 class SourceActivity: Activity() { fun go() { val data = “hogefuga” startActivity(TargetActivity.intent(this, data)) } } thisを書きたくない! 簡単には拡張関数に できなさそう...

Slide 18

Slide 18 text

Intent生成を遅らせる: 遷移先 class TargetActivity: Activity() { companion object { fun intent(data: String) = { c: Context -> Intent(c, TargetActivity::class.java) .putExtra(“data”, data) } } }

Slide 19

Slide 19 text

Intent生成を遅らせる: 遷移先 class TargetActivity: Activity() { companion object { fun intent(data: String) = { c: Context -> Intent(c, TargetActivity::class.java) .putExtra(“data”, data) } } } Contextを取らなくなった

Slide 20

Slide 20 text

Intent生成を遅らせる: 遷移先 class TargetActivity: Activity() { companion object { fun intent(data: String) = { c: Context -> Intent(c, TargetActivity::class.java) .putExtra(“data”, data) } } } Context -> Intentな 関数を返す

Slide 21

Slide 21 text

イマイチな使用例: 遷移元 class SourceActivity: Activity() { fun go() { val data = “hogefuga” startActivity(TargetActivity.intent(data)(this)) } }

Slide 22

Slide 22 text

よさげな使用例: 遷移元 class SourceActivity: Activity() { fun go() { val data = “hogefuga” TargetActivity.intent(data).start() } fun ((Context)->Intent).start() { startActivity(this(applicationContext)) } }

Slide 23

Slide 23 text

よさげな使用例: 遷移元 class SourceActivity: Activity() { fun go() { val data = “hogefuga” TargetActivity.intent(data).start() } fun ((Context)->Intent).start() { startActivity(this(applicationContext)) } } ここからthisが消えた

Slide 24

Slide 24 text

共通部品化する for 遷移先 inline fun intentBuilder(crossinline init: Intent.() -> Unit) = { context: Context -> Intent(context, T::class.java).apply { init() } }

Slide 25

Slide 25 text

共通部品を使う: 遷移先 class TargetActivity: Activity() { companion object { fun intent(data: String) = intentBuilder { putExtra(“data”, data) } } }

Slide 26

Slide 26 text

共通部品化する for 遷移元 interface IntentFeature { fun startActivity(intent: Intent) fun getApplicationContext() fun ((Context)->Intent).start() { startActivity(this(getApplicationContext())) } } インタフェースを継承するので はなく、抽象メソッドを定義して おく

Slide 27

Slide 27 text

共通部品を使う: 遷移元 class SourceActivity: Activity(), IntentFeature { fun go() { val data = “hogefuga” TargetActivity.intent(data).start() } }

Slide 28

Slide 28 text

おまけ: M11以前 trait IntentFeature: Activity { fun ((Context)->Intent).start() { startActivity(this(getApplicationContext())) } } 実装する側のクラスを 指定できた

Slide 29

Slide 29 text

Thank you, Enjoy Kotlin!