Upgrade to Pro — share decks privately, control downloads, hide ads and more …

KotlinとモダンなライブラリーでAndroidアプリを作るっ

 KotlinとモダンなライブラリーでAndroidアプリを作るっ

E28404a128b6014e6f499d2a967c72a0?s=128

Takuji Nishibayashi

April 02, 2016
Tweet

Transcript

  1. KotlinͱϞμϯͳϥΠϒϥϦʔ ͰAndroidΞϓϦΛ࡞Δͬ ͨ͘͡ (@takuji31)

  2. @takuji31 (Takuji Nishibayashi) Application Engineer at Hatena

  3. Loves Kotlin

  4. KotlinͰΞϓϦ։ൃத (ϓϥΠϕʔτͰ)

  5. AGENDA • KotlinͰAndroidΞϓϦΛ࡞Δ • KotlinͰJavaͷϥΠϒϥϦʔΛ࢖͏ • KotlinͷϥΠϒϥϦʔΛ࢖͏

  6. Kotlin 1.0.0 released

  7. Kotlin 1.0.1-2 released

  8. KotlinͰ AndroidΞϓ ϦΛ࡞Δ

  9. Android Java = Java6 + α

  10. + α

  11. Diamond operator

  12. Multi catch

  13. try-with-resources (4.4~)

  14. ͭΒ͍

  15. Kotlin

  16. Null-safe

  17. Property

  18. Delegate

  19. Lambda expression

  20. Extension

  21. Smart cast

  22. ߴ͍Javaͱͷ ૬ޓӡ༻ੑ

  23. JetBrainsࣗମ͕ Androidαϙʔτʹྗ ΛೖΕ͍ͯΔ

  24. ࠷ߴ

  25. KotlinͰJava ͷϥΠϒϥϦʔ Λ࢖͏

  26. Dagger2

  27. ίϯύΠϧλΠϜʹ ґଘΛղܾ͢Δ DIίϯςφ

  28. Component/Module

  29. Module͕ ґଘΛఏڙ

  30. Component͕ ґଘΛ஫ೖ

  31. KotlinͰͷ࢖͍ํ

  32. build.gradle dependencies { compile 'com.google.dagger:dagger:2.1'
 kapt "com.google.dagger:dagger-compiler:2.1"
 compile 'javax.annotation:javax.annotation-api:1.2'
 }

    kapt {
 generateStubs = true
 }

  33. build.gradle dependencies { compile 'com.google.dagger:dagger:2.1'
 kapt "com.google.dagger:dagger-compiler:2.1"
 compile 'javax.annotation:javax.annotation-api:1.2'
 }

    kapt {
 generateStubs = true
 }
 LBQUͰ,PUMJOͷΫϥεʹ ରͯ͠"15Λ࣮ߦͰ͖ΔΑ͏ʹ͢Δ
  34. build.gradle dependencies { compile 'com.google.dagger:dagger:2.1'
 kapt "com.google.dagger:dagger-compiler:2.1"
 compile 'javax.annotation:javax.annotation-api:1.2'
 }

    kapt {
 generateStubs = true
 }
 LBQUͰ,PUMJOͷΫϥεʹ ରͯ͠"15Λ࣮ߦͰ͖ΔΑ͏ʹ͢Δ ίϯύΠϧ࣌ʹ+BWBͰTUVCϑΝΠϧΛੜ੒ ͢Δ͜ͱͰɺ"15Ͱੜ੒͞ΕͨΫϥεΛ ,PUMJOͰ΋ѻ͑ΔΑ͏ʹ͢Δ
  35. Module @Module
 class AppModule(@get:Provides val context: Context) {
 @Provides fun

    notificationManager(context: Context) : NotificationManager = context.getSystemService( Context.NOTIFICATION_SERVICE) as NotificationManager
 }
  36. Module @Module
 class AppModule(@get:Provides val context: Context) {
 @Provides fun

    notificationManager(context: Context) : NotificationManager = context.getSystemService( Context.NOTIFICATION_SERVICE) as NotificationManager
 } (FUUFSʹ1SPWJEFTBOOPUBUJPOΛ͚ͭΔ
  37. Module @Module
 class AppModule(@get:Provides val context: Context) {
 @Provides fun

    notificationManager(context: Context) : NotificationManager = context.getSystemService( Context.NOTIFICATION_SERVICE) as NotificationManager
 } (FUUFSʹ1SPWJEFTBOOPUBUJPOΛ͚ͭΔ ґଘΛఏڙ͢Δϝιουʹ 1SPWJEFTBOOPUBUJPOΛ͚ͭΔ
  38. Component @Component(modules = arrayOf(AppModule::class))
 interface AppComponent {
 val context: Context


    val notificationManager: NotificationManager
 
 fun inject(mainActivity: MainActivity)
 }
  39. Component @Component(modules = arrayOf(AppModule::class))
 interface AppComponent {
 val context: Context


    val notificationManager: NotificationManager
 
 fun inject(mainActivity: MainActivity)
 } ௚઀औಘ͢ΔͨΊʹϓϩύςΟʔ ϝιουͰ΋Α͍ ΛఆٛͰ͖Δ
  40. Component @Component(modules = arrayOf(AppModule::class))
 interface AppComponent {
 val context: Context


    val notificationManager: NotificationManager
 
 fun inject(mainActivity: MainActivity)
 } ௚઀औಘ͢ΔͨΊʹϓϩύςΟʔ ϝιουͰ΋Α͍ ΛఆٛͰ͖Δ ஫ೖ͢ΔͨΊͷϝιουΛ ఆٛ͢Δ
  41. Application class class App : Application() {
 val component :

    AppComponent by lazy {
 DaggerAppComponent .builder().appModule(AppModule(this)).build()
 }
 override fun onCreate() {
 super.onCreate()
 }
 }
  42. Application class class App : Application() {
 val component :

    AppComponent by lazy {
 DaggerAppComponent .builder().appModule(AppModule(this)).build()
 }
 override fun onCreate() {
 super.onCreate()
 }
 } $PNQPOFOUΛอ࣋͢ΔͨΊͷ ϓϩύςΟʔΛ࡞Δ
  43. Application class class App : Application() {
 val component :

    AppComponent by lazy {
 DaggerAppComponent .builder().appModule(AppModule(this)).build()
 }
 override fun onCreate() {
 super.onCreate()
 }
 } $PNQPOFOUΛอ࣋͢ΔͨΊͷ ϓϩύςΟʔΛ࡞Δ MB[ZΛ࢖͏͜ͱͰ ॳճΞΫηε࣌ʹॳظԽ
  44. Application class class App : Application() {
 val component :

    AppComponent by lazy {
 DaggerAppComponent .builder().appModule(AppModule(this)).build()
 }
 override fun onCreate() {
 super.onCreate()
 }
 } $PNQPOFOUΛอ࣋͢ΔͨΊͷ ϓϩύςΟʔΛ࡞Δ MB[ZΛ࢖͏͜ͱͰ ॳճΞΫηε࣌ʹॳظԽ "15Ͱੜ੒͞ΕͨΫϥεΛ ࡞ͬͯฦ͢
  45. Target class MainActivity : AppCompatActivity() {
 @Inject
 lateinit var context

    : Context
 
 @Inject
 lateinit var notificationManager : NotificationManager
 
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)
 app.component.inject(mainActivity = this)
 }
 }
  46. Target class MainActivity : AppCompatActivity() {
 @Inject
 lateinit var context

    : Context
 
 @Inject
 lateinit var notificationManager : NotificationManager
 
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)
 app.component.inject(mainActivity = this)
 }
 } *OKFDUBOOPUBUJPOΛ͚ͭͨ QSPQFSUZ΍ϝιουʹґଘ஫ೖ͞ΕΔ
  47. Target class MainActivity : AppCompatActivity() {
 @Inject
 lateinit var context

    : Context
 
 @Inject
 lateinit var notificationManager : NotificationManager
 
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)
 app.component.inject(mainActivity = this)
 }
 } *OKFDUBOOPUBUJPOΛ͚ͭͨ QSPQFSUZ΍ϝιουʹґଘ஫ೖ͞ΕΔ MBUFJOJUΛ͚ͭΔ͜ͱͰॳظԽ͕ෆཁʹͳΓɺ ͔ͭϑΟʔϧυʹ+BWB͔Β௚઀୅ೖͰ͖ΔΑ͏ʹ
  48. Target class MainActivity : AppCompatActivity() {
 @Inject
 lateinit var context

    : Context
 
 @Inject
 lateinit var notificationManager : NotificationManager
 
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)
 app.component.inject(mainActivity = this)
 }
 } *OKFDUBOOPUBUJPOΛ͚ͭͨ QSPQFSUZ΍ϝιουʹґଘ஫ೖ͞ΕΔ MBUFJOJUΛ͚ͭΔ͜ͱͰॳظԽ͕ෆཁʹͳΓɺ ͔ͭϑΟʔϧυʹ+BWB͔Β௚઀୅ೖͰ͖ΔΑ͏ʹ $PNQPOFOUͷJOKFDUϝιουʹର৅ͷΠϯελϯε Λ౉͢ BQQ͸"QQΛऔಘ͢Δ֦ுϓϩύςΟʔ
  49. Data Binding Library

  50. Androidެࣜͷσʔ λʔόΠϯσΟϯά ϥΠϒϥϦʔ

  51. Android Studio ʹΑΔαϙʔτ (ίʔυิ׬ɺγϯ λοΫεϋΠϥΠτ)

  52. Ұํ޲/૒ํ޲ͷόΠ ϯσΟϯάαϙʔτ

  53. KotlinͰ΋ ࢖͑Δ

  54. build.gradle android {
 dataBinding {
 enabled = true
 }
 }


    
 dependencies {
 kapt 'com.android.databinding:compiler:2.1.0-alpha5'
 }
 kapt {
 generateStubs = true
 }
  55. όΠϯυ͍ͨ͠ΫϥεΛ࡞Δ data class User(val name: String, val birthDay: String?)

  56. ϨΠΞ΢τͷXMLͰ όΠϯσΟϯάΛఆٛ

  57. ϨΠΞ΢τͷXML(Ұ෦ུ) <layout>
 <data>
 <variable name=“user" type="jp.takuji31.kotlindatabinding.User" />
 <variable name=“randomButtonClickListener” type="android.view.View.OnClickListener"

    />
 <import type="android.view.View" />
 </data>
 <RelativeLayout>
 <TextView android:text="Name : "/>
 <TextView android:text="@{user.name}" tools:text="namename" />
 <TextView android:text="Birthday : "
 android:visibility="@{user.birthDay != null ? View.VISIBLE : View.GONE}" />
 <TextView android:text=“@{user.birthDay}" tools:text="1970/01/01"
 android:visibility="@{user.birthDay != null ? View.VISIBLE : View.GONE}” />
 <Button android:onClick="@{randomButtonClickListener}"/>
 </RelativeLayout>
 </layout>
  58. ϨΠΞ΢τͷXML(Ұ෦ུ) <layout>
 <data>
 <variable name=“user" type="jp.takuji31.kotlindatabinding.User" />
 <variable name=“randomButtonClickListener” type="android.view.View.OnClickListener"

    />
 <import type="android.view.View" />
 </data>
 <RelativeLayout>
 <TextView android:text="Name : "/>
 <TextView android:text="@{user.name}" tools:text="namename" />
 <TextView android:text="Birthday : "
 android:visibility="@{user.birthDay != null ? View.VISIBLE : View.GONE}" />
 <TextView android:text=“@{user.birthDay}" tools:text="1970/01/01"
 android:visibility="@{user.birthDay != null ? View.VISIBLE : View.GONE}” />
 <Button android:onClick="@{randomButtonClickListener}"/>
 </RelativeLayout>
 </layout> ϧʔτཁૉ͸MBZPVU
  59. ϨΠΞ΢τͷXML(Ұ෦ུ) <layout>
 <data>
 <variable name=“user" type="jp.takuji31.kotlindatabinding.User" />
 <variable name=“randomButtonClickListener” type="android.view.View.OnClickListener"

    />
 <import type="android.view.View" />
 </data>
 <RelativeLayout>
 <TextView android:text="Name : "/>
 <TextView android:text="@{user.name}" tools:text="namename" />
 <TextView android:text="Birthday : "
 android:visibility="@{user.birthDay != null ? View.VISIBLE : View.GONE}" />
 <TextView android:text=“@{user.birthDay}" tools:text="1970/01/01"
 android:visibility="@{user.birthDay != null ? View.VISIBLE : View.GONE}” />
 <Button android:onClick="@{randomButtonClickListener}"/>
 </RelativeLayout>
 </layout> ϧʔτཁૉ͸MBZPVU όΠϯσΟϯάΫϥεͷ ϓϩύςΟʔΛఆٛ
  60. ϨΠΞ΢τͷXML(Ұ෦ུ) <layout>
 <data>
 <variable name=“user" type="jp.takuji31.kotlindatabinding.User" />
 <variable name=“randomButtonClickListener” type="android.view.View.OnClickListener"

    />
 <import type="android.view.View" />
 </data>
 <RelativeLayout>
 <TextView android:text="Name : "/>
 <TextView android:text="@{user.name}" tools:text="namename" />
 <TextView android:text="Birthday : "
 android:visibility="@{user.birthDay != null ? View.VISIBLE : View.GONE}" />
 <TextView android:text=“@{user.birthDay}" tools:text="1970/01/01"
 android:visibility="@{user.birthDay != null ? View.VISIBLE : View.GONE}” />
 <Button android:onClick="@{randomButtonClickListener}"/>
 </RelativeLayout>
 </layout> ϧʔτཁૉ͸MBZPVU όΠϯσΟϯάΫϥεͷ ϓϩύςΟʔΛఆٛ ఆٛͨ͠ϓϩύςΟʔ΍ ͦͷϓϩύςΟʔΛόΠ ϯσΟϯά
  61. ϨΠΞ΢τͷXML(Ұ෦ུ) <layout>
 <data>
 <variable name=“user" type="jp.takuji31.kotlindatabinding.User" />
 <variable name=“randomButtonClickListener” type="android.view.View.OnClickListener"

    />
 <import type="android.view.View" />
 </data>
 <RelativeLayout>
 <TextView android:text="Name : "/>
 <TextView android:text="@{user.name}" tools:text="namename" />
 <TextView android:text="Birthday : "
 android:visibility="@{user.birthDay != null ? View.VISIBLE : View.GONE}" />
 <TextView android:text=“@{user.birthDay}" tools:text="1970/01/01"
 android:visibility="@{user.birthDay != null ? View.VISIBLE : View.GONE}” />
 <Button android:onClick="@{randomButtonClickListener}"/>
 </RelativeLayout>
 </layout> ϧʔτཁૉ͸MBZPVU όΠϯσΟϯάΫϥεͷ ϓϩύςΟʔΛఆٛ +BWBಉ༷ʹJNQPSUՄೳ ఆٛͨ͠ϓϩύςΟʔ΍ ͦͷϓϩύςΟʔΛόΠ ϯσΟϯά
  62. ϨΠΞ΢τͷXML(Ұ෦ུ) <layout>
 <data>
 <variable name=“user" type="jp.takuji31.kotlindatabinding.User" />
 <variable name=“randomButtonClickListener” type="android.view.View.OnClickListener"

    />
 <import type="android.view.View" />
 </data>
 <RelativeLayout>
 <TextView android:text="Name : "/>
 <TextView android:text="@{user.name}" tools:text="namename" />
 <TextView android:text="Birthday : "
 android:visibility="@{user.birthDay != null ? View.VISIBLE : View.GONE}" />
 <TextView android:text=“@{user.birthDay}" tools:text="1970/01/01"
 android:visibility="@{user.birthDay != null ? View.VISIBLE : View.GONE}” />
 <Button android:onClick="@{randomButtonClickListener}"/>
 </RelativeLayout>
 </layout> ϧʔτཁૉ͸MBZPVU όΠϯσΟϯάΫϥεͷ ϓϩύςΟʔΛఆٛ +BWBಉ༷ʹJNQPSUՄೳ ఆٛͨ͠ϓϩύςΟʔ΍ ͦͷϓϩύςΟʔΛόΠ ϯσΟϯά Ұ෦ͷԋࢉࢠ΋࢖͑Δ
  63. ϨΠΞ΢τͷXML(Ұ෦ུ) <layout>
 <data>
 <variable name=“user" type="jp.takuji31.kotlindatabinding.User" />
 <variable name=“randomButtonClickListener” type="android.view.View.OnClickListener"

    />
 <import type="android.view.View" />
 </data>
 <RelativeLayout>
 <TextView android:text="Name : "/>
 <TextView android:text="@{user.name}" tools:text="namename" />
 <TextView android:text="Birthday : "
 android:visibility="@{user.birthDay != null ? View.VISIBLE : View.GONE}" />
 <TextView android:text=“@{user.birthDay}" tools:text="1970/01/01"
 android:visibility="@{user.birthDay != null ? View.VISIBLE : View.GONE}” />
 <Button android:onClick="@{randomButtonClickListener}"/>
 </RelativeLayout>
 </layout> ϧʔτཁૉ͸MBZPVU όΠϯσΟϯάΫϥεͷ ϓϩύςΟʔΛఆٛ +BWBಉ༷ʹJNQPSUՄೳ ఆٛͨ͠ϓϩύςΟʔ΍ ͦͷϓϩύςΟʔΛόΠ ϯσΟϯά Ұ෦ͷԋࢉࢠ΋࢖͑Δ 0O$MJDL-JTUFOFS΋ઃఆՄ
  64. ఆٛΛݩʹAPTͰ ΫϥεΛࣗಈੜ੒

  65. όΠϯυ͢Δ class DataClassActivity : AppCompatActivity() {
 var users = listOf(


    User(name = "takuji31", birthDay = "1987/03/01"),
 User(name = "takuji32", birthDay = "1987/03/02"),
 User(name = "takuji33", birthDay = "1987/03/03"),
 User(name = "takuji24884", birthDay = null)
 )
 val binding: ActivityDataClassBinding by lazy {
 DataBindingUtil.setContentView<ActivityDataClassBinding>(this, R.layout.activity_data_class)
 }
 override fun onCreate(savedInstanceState: Bundle?) {
 binding.user = users.last()
 binding.randomButtonClickListener = View.OnClickListener {
 binding.user = users[0]
 users = users.drop(1) + binding.user
 }
 }
 }
  66. όΠϯυ͢Δ class DataClassActivity : AppCompatActivity() {
 var users = listOf(


    User(name = "takuji31", birthDay = "1987/03/01"),
 User(name = "takuji32", birthDay = "1987/03/02"),
 User(name = "takuji33", birthDay = "1987/03/03"),
 User(name = "takuji24884", birthDay = null)
 )
 val binding: ActivityDataClassBinding by lazy {
 DataBindingUtil.setContentView<ActivityDataClassBinding>(this, R.layout.activity_data_class)
 }
 override fun onCreate(savedInstanceState: Bundle?) {
 binding.user = users.last()
 binding.randomButtonClickListener = View.OnClickListener {
 binding.user = users[0]
 users = users.drop(1) + binding.user
 }
 }
 } MB[Z΍OPU/VMMͷEFMFHBUFΛ࢖ͬͯ όΠϯσΟϯάΫϥεͷ ϓϩύςΟʔΛ༻ҙ͢ΔͱΑ͍
  67. όΠϯυ͢Δ class DataClassActivity : AppCompatActivity() {
 var users = listOf(


    User(name = "takuji31", birthDay = "1987/03/01"),
 User(name = "takuji32", birthDay = "1987/03/02"),
 User(name = "takuji33", birthDay = "1987/03/03"),
 User(name = "takuji24884", birthDay = null)
 )
 val binding: ActivityDataClassBinding by lazy {
 DataBindingUtil.setContentView<ActivityDataClassBinding>(this, R.layout.activity_data_class)
 }
 override fun onCreate(savedInstanceState: Bundle?) {
 binding.user = users.last()
 binding.randomButtonClickListener = View.OnClickListener {
 binding.user = users[0]
 users = users.drop(1) + binding.user
 }
 }
 } MB[Z΍OPU/VMMͷEFMFHBUFΛ࢖ͬͯ όΠϯσΟϯάΫϥεͷ ϓϩύςΟʔΛ༻ҙ͢ΔͱΑ͍ ࣗಈੜ੒͞ΕΔΫϥεʹ͸ఆ໊ٛͨ͠લͱಉ ͡ϓϩύςΟʔ ਖ਼֬ʹ͸TFUUFSHFUUFS ͕ ੜ੒͞ΕΔͷͰɺηοτ͢Δͱ஋͕൓ө͞Ε Δ
  68. None
  69. None
  70. (ViewClass)findById(R.id.vi ewId)͸΋͏ෆཁͰ͢

  71. Define binding <layout>
 
 <android.support.v7.widget.RecyclerView
 android:id="@+id/recyclerView"
 android:layout_width="match_parent"
 android:layout_height="match_parent"/>
 </layout>

  72. Define binding <layout>
 
 <android.support.v7.widget.RecyclerView
 android:id="@+id/recyclerView"
 android:layout_width="match_parent"
 android:layout_height="match_parent"/>
 </layout> JEΛTOBLF@DBTF͔

    MPXFS$BNFM$BTFͰఆٛ
  73. Field access class MainActivity : AppCompatActivity() {
 val binding :

    ActivityMainBinding by lazy {DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)} 
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 binding.recyclerView.layoutManager = LinearLayoutManager(this)
 }
 }
  74. Field access class MainActivity : AppCompatActivity() {
 val binding :

    ActivityMainBinding by lazy {DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)} 
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 binding.recyclerView.layoutManager = LinearLayoutManager(this)
 }
 } MPXFS$BNFM$BTFͰϑΟʔϧ υ͕ੜ੒͞ΕΔ
  75. Property observer

  76. มߋ؂ࢹՄೳͳσʔλʔΫϥε class Counter : BaseObservable() {
 @get:Bindable
 var count :

    Int = 0
 set(value) {
 field = value
 notifyPropertyChanged(BR.count)
 }
 }

  77. มߋ؂ࢹՄೳͳσʔλʔΫϥε class Counter : BaseObservable() {
 @get:Bindable
 var count :

    Int = 0
 set(value) {
 field = value
 notifyPropertyChanged(BR.count)
 }
 }
 มߋ؂ࢹΛ͍ͨ͠৔߹͸ #BTF0CTFSWBCMFΛܧঝ
  78. มߋ؂ࢹՄೳͳσʔλʔΫϥε class Counter : BaseObservable() {
 @get:Bindable
 var count :

    Int = 0
 set(value) {
 field = value
 notifyPropertyChanged(BR.count)
 }
 }
 มߋ؂ࢹΛ͍ͨ͠৔߹͸ #BTF0CTFSWBCMFΛܧঝ ؂ࢹ͍ͨ͠ϓϩύςΟʔͷ HFUUFSʹ#JOEBCMF BOOPUBUJPOΛ͚ͭΔ
  79. มߋ؂ࢹՄೳͳσʔλʔΫϥε class Counter : BaseObservable() {
 @get:Bindable
 var count :

    Int = 0
 set(value) {
 field = value
 notifyPropertyChanged(BR.count)
 }
 }
 มߋ؂ࢹΛ͍ͨ͠৔߹͸ #BTF0CTFSWBCMFΛܧঝ ؂ࢹ͍ͨ͠ϓϩύςΟʔͷ HFUUFSʹ#JOEBCMF BOOPUBUJPOΛ͚ͭΔ ஋͕มߋ͞Εͨ͜ͱΛ௨஌
  80. όΠϯσΟϯάΛఆٛ <layout>
 <data>
 <variable name=“counter" type=“…PropertyObserverActivity.Counter” />
 <variable name="buttonClickListener"
 type="android.view.View.OnClickListener"

    />
 </data>
 <LinearLayout>
 <TextView android:text="@{@string/count_format(counter.count)}"/>
 <Button android:onClick=“@{buttonClickListener}" />
 </LinearLayout>
 </layout>

  81. Change value class PropertyObserverActivity : AppCompatActivity() {
 val binding :

    ActivityPropertyObserverBinding by lazy { DataBindingUtil.setContentView( this, R.layout.activity_property_observer ) } 
 override fun onCreate(savedInstanceState: Bundle?) {
 val counter = Counter()
 binding.counter = counter
 binding.buttonClickListener = View.OnClickListener {
 counter.count += 1 }
 }
 }
  82. Change value class PropertyObserverActivity : AppCompatActivity() {
 val binding :

    ActivityPropertyObserverBinding by lazy { DataBindingUtil.setContentView( this, R.layout.activity_property_observer ) } 
 override fun onCreate(savedInstanceState: Bundle?) {
 val counter = Counter()
 binding.counter = counter
 binding.buttonClickListener = View.OnClickListener {
 counter.count += 1 }
 }
 } ஋Ληοτ͢Δ͚ͩͰ มߋ͕൓ө͞ΕΔ
  83. None
  84. None
  85. Binding adapter

  86. Viewͷଐੑʹ஋Λ ηοτ͢ΔॲཧΛఆٛ ͢Δ࢓૊Έ

  87. BindingAdapterΛఆٛ object Adapters {
 @JvmStatic
 @BindingAdapter("android:text")
 fun convertZonedDateTimeToString (textView: TextView,

    zonedDateTime : ZonedDateTime) {
 val timeString = zonedDateTime.format( DateTimeFormatter.ofPattern("yyyy/MM/dd/ HH:mm:SS"))
 textView.text = timeString
 }
 }
  88. BindingAdapterΛఆٛ object Adapters {
 @JvmStatic
 @BindingAdapter("android:text")
 fun convertZonedDateTimeToString (textView: TextView,

    zonedDateTime : ZonedDateTime) {
 val timeString = zonedDateTime.format( DateTimeFormatter.ofPattern("yyyy/MM/dd/ HH:mm:SS"))
 textView.text = timeString
 }
 } +WN4UBUJDBOOPUBUJPOΛ ͚ͭΔ͜ͱͰTUBUJDϝιουͱͯ͠ఆٛ͞ΕΔ
  89. BindingAdapterΛఆٛ object Adapters {
 @JvmStatic
 @BindingAdapter("android:text")
 fun convertZonedDateTimeToString (textView: TextView,

    zonedDateTime : ZonedDateTime) {
 val timeString = zonedDateTime.format( DateTimeFormatter.ofPattern("yyyy/MM/dd/ HH:mm:SS"))
 textView.text = timeString
 }
 } +WN4UBUJDBOOPUBUJPOΛ ͚ͭΔ͜ͱͰTUBUJDϝιουͱͯ͠ఆٛ͞ΕΔ BOESPJEUFYUଐੑ΁஋Λ ηοτͰ͖Δ
  90. BindingAdapterΛఆٛ object Adapters {
 @JvmStatic
 @BindingAdapter("android:text")
 fun convertZonedDateTimeToString (textView: TextView,

    zonedDateTime : ZonedDateTime) {
 val timeString = zonedDateTime.format( DateTimeFormatter.ofPattern("yyyy/MM/dd/ HH:mm:SS"))
 textView.text = timeString
 }
 } +WN4UBUJDBOOPUBUJPOΛ ͚ͭΔ͜ͱͰTUBUJDϝιουͱͯ͠ఆٛ͞ΕΔ BOESPJEUFYUଐੑ΁஋Λ ηοτͰ͖Δ 5FYU7JFXͱ;POFE%BUF5JNF ͷ૊Έ߹Θͤͷ࣌ʹݺ͹ΕΔ
  91. ϨΠΞ΢τΛॻ͘ <layout>
 <data>
 <variable
 name="now"
 type="org.threeten.bp.ZonedDateTime" />
 </data>
 <TextView android:text="@{now}"/>


    </layout>
  92. ϨΠΞ΢τΛॻ͘ <layout>
 <data>
 <variable
 name="now"
 type="org.threeten.bp.ZonedDateTime" />
 </data>
 <TextView android:text="@{now}"/>


    </layout> ஋ΛόΠϯυ͢Δ͚ͩͰ0,
  93. ஋Ληοτ͢Δ class NowActivity : AppCompatActivity() {
 
 val binding :

    ActivityNowBinding by lazy {
 DataBindingUtil.setContentView<ActivityNowBinding>(this, R.layout.activity_now)
 }
 
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 binding.now = ZonedDateTime.now()
 }
 }
  94. ஋Ληοτ͢Δ class NowActivity : AppCompatActivity() {
 
 val binding :

    ActivityNowBinding by lazy {
 DataBindingUtil.setContentView<ActivityNowBinding>(this, R.layout.activity_now)
 }
 
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 binding.now = ZonedDateTime.now()
 }
 } ஋Ληοτ͢Δ
  95. Value converter

  96. ಛఆͷΫϥεͷ஋Λ ViewʹઃఆͰ͖Δ஋ ʹม׵͢Δ࢓૊Έ

  97. KotlinͰఆٛͯ͠΋ Data Binding Libraryͷ ίϯύΠϥʔ͕ೝࣝ͠ͳ͍

  98. JavaͰॻ͖·͠ΐ͏

  99. BindingAdapterΛఆٛ public class Converters {
 @BindingConversion
 public static ColorDrawable convertColorStringToColor(String

    colorString) {
 return new ColorDrawable(Color.parseColor(colorString));
 }
 }

  100. BindingAdapterΛఆٛ public class Converters {
 @BindingConversion
 public static ColorDrawable convertColorStringToColor(String

    colorString) {
 return new ColorDrawable(Color.parseColor(colorString));
 }
 }
 $PMPS%SBXBCMF͕ηοτͰ͖Δଐੑʹ 4USJOHΛόΠϯυ͠Α͏ͱͨ࣌͠ʹݺ͹ΕΔ
  101. ϨΠΞ΢τΛॻ͘ <layout>
 <data>
 <variable name="backgroundColor" type="String"/>
 </data>
 <View
 android:background="@{backgroundColor}"/>
 </layout>

  102. ϨΠΞ΢τΛॻ͘ <layout>
 <data>
 <variable name="backgroundColor" type="String"/>
 </data>
 <View
 android:background="@{backgroundColor}"/>
 </layout>

    ஋ΛόΠϯυ͢Δ͚ͩͰ0,
  103. ஋Ληοτ͢Δ class ColoredActivity : AppCompatActivity() {
 
 val binding :

    ActivityColoredBinding by lazy {
 DataBindingUtil.setContentView<ActivityColoredBinding>(this, R.layout.activity_colored)
 }
 
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 binding.backgroundColor = "#00FF00"
 }
 }

  104. ஋Ληοτ͢Δ class ColoredActivity : AppCompatActivity() {
 
 val binding :

    ActivityColoredBinding by lazy {
 DataBindingUtil.setContentView<ActivityColoredBinding>(this, R.layout.activity_colored)
 }
 
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 binding.backgroundColor = "#00FF00"
 }
 }
 ஋Ληοτ͢Δ
  105. None
  106. example : github.com/ takuji31/ KotlinDataBinding

  107. Realm

  108. Post SQLite ͳ ϞόΠϧ޲͚ DBϥΠϒϥϦʔ

  109. ࣌ؒͳ͍ͷͰলུ

  110. github.com/realm/ realm-java/tree/ master/examples/ kotlinExample

  111. Orma

  112. AnnotationͰఆٛΛ ॻΔAndroid޲͚ͷ O/R mapper

  113. ※Dagger2ͱ࢖͏৔߹͸ɺ ModuleΛJavaͰॻ͔ͳ͍ͱ ੜ੒͞ΕͨϑΝΠϧΛೝࣝͰ ͖ͳ͍

  114. ࣌ؒͳ͍ͷͰলུ

  115. github.com/gfx/ Orma-Kotlin-Example

  116. Kotlinͷ ϥΠϒϥϦʔ Λ࢖͏

  117. anko

  118. JetBrains੡ͷ Android༻ ศརϥΠϒϥϦʔ

  119. DSLʹΑΔViewఆٛ (Android Studioͷ ϨΠΞ΢τϓϨϏϡʔରԠ)

  120. AndroidͷContext ΁ͷศར֦ு (GenericsͰIntentੜ੒ɺ Α͘࢖͏Intentੜ੒ؔ਺ͳͲ)

  121. SQLiteͷϔϧύʔ

  122. ͳͲͳͲ

  123. DSL͸Data Binding Libraryͱ͸૊Έ߹Θ ͤΒΕͳ͍

  124. github.com/Kotlin/ anko

  125. Koreference

  126. SharedPreferencesͷ஋ʹϓ ϩύςΟʔΞΫηε͢ΔͨΊ ͷϥΠϒϥϦʔ

  127. ಛ௃ • ؆୯ʹ Preference model తͳ΋ͷΛॻ͚Δ • Null-SafeͳSharedPreference • جຊతͳSharedPreferencesͷܕΛαϙʔτ

    • ֦ுՄೳͳDelegated Property • Gson αϙʔτ͋Γ
  128. Easy to make Preference model public class MyPreference( pref :

    SharedPreferences ) : SharedPreferences by pref {
 public var name : String by stringPreference("")
 }
  129. Null-Safe SharedPreferences public class MyPreference( pref : SharedPreferences ) :

    SharedPreferences by pref {
 public var firstName : String by stringPreference("")
 public var lastName : String by stringPreference("")
 public var middleName : String? by nullableStringPreference(null)
 }
  130. All Preference type support public class MyPreference(pref : SharedPreferences) :

    SharedPreferences by pref {
 public var stringValue : String by stringPreference("default value")
 public var intValue : Int by intPreference(256)
 public var longValue : Long by longPreference(256L)
 public var floatValue : Float by floatPreference(12.34f)
 public var boolValue : Boolean by booleanPreference(true)
 public var stringSetValue : Set<String> by stringSetPreference(setOf()) public var stringValue : String? by nullableStringPreference()
 public var stringSetValue : Set<String>? by nullableStringSetPreference() 
 }
  131. Easy to create custom delegate property public class ByteArrayPreference( default

    : ByteArray = byteArrayOf(), name : String? = null ) : KoreferenceDelegate<ByteArray, String>(default,name), StringPreference {
 override fun toModelValue(value: String): ByteArray {
 return Base64.decode(value, Base64.DEFAULT)
 }
 
 override fun toPreferenceValue(value: ByteArray): String {
 return Base64.encodeToString(value, Base64.DEFAULT)
 }
 }
  132. Easy to create custom delegate property public class RealmPreference( pref

    : SharedPreferences ) : SharedPreferences by pref {
 var encryptionKey : ByteArray by ByteArrayPreference()
 } val pref = getSharedPreferences("realm",Context.MODE_PRIVATE)
 val model = RealmPreference(pref)
 model.encryptionKey
  133. github.com/takuji31/ Koreference

  134. ·ͱΊ • AndroidͰKotlinΛ࢖͏ͷ͸ݱ࣮తʹͳΓͭͭ͋Δ • JavaͷϥΠϒϥϦʔ͸͍͍ͩͨͦͷ··࢖͑Δ • APTΛ࢖͏ϥΠϒϥϦʔ΋Ұ෦Λআ͍ͯී௨ʹ࢖͑Δ • Kotlinಛ༗ͷػೳΛར༻ͨ͠ϥΠϒϥϦʔͰ΋ͬͱॻ ͖΍͘͢Ͱ͖Δ

  135. ؔ੢Kotlinษڧձ ఆظ։࠵͢Δͧʂ

  136. ଓใΛ͓଴͍ͪͩ͘͞

  137. Enjoy Kotlin Android life!