Share
Embed
Transcript
39 slides
-
Copyright © Sansan, Inc. All rights reserved. > ObservableArray >
Pikkel Jumpei Yamamoto 2016.7.1 第3回 Kotlin勉強会 in Sansan #kotlin_sansan -
Copyright © Sansan, Inc. All rights reserved. > ⾃⼰紹介 -
⼭本純平 - Sansan株式会社 Eight事業部 - EightのAndroidアプリの開発 - twitter: @boohbah - github: https://github.com/yamamotoj -
Copyright © Sansan, Inc. All rights reserved. > Eightの新機能「オンライン名刺交換」 -
もう紙の名刺はいらない! - NearByで周囲のEightユー ザーを検索 - 複数のユーザー間でも名刺 交換ができる -
Copyright © Sansan, Inc. All rights reserved. > アジェンダ -
⾃作のライブラリを2つ紹介 - ObservableArray - Pikkel -
Copyright © Sansan, Inc. All rights reserved. > ObservableArrayとは -
変更の通知を受け取れるArray Interface -
Copyright © Sansan, Inc. All rights reserved. > ObservableArray interface
ObservableArray<T> { val size: Int operator fun get(index: Int): T fun updates(): Observable<Event> sealed class Event { class DataSetChanged : Event() class ItemChanged(val position: Int) : Event() class ItemInserted(val position: Int) : Event() class ItemRemoved(val position: Int) : Event() } } -
Copyright © Sansan, Inc. All rights reserved. > ObservableArray interface
ObservableArray<T> { val size: Int operator fun get(index: Int): T fun updates(): Observable<Event> sealed class Event { class DataSetChanged : Event() class ItemChanged(val position: Int) : Event() class ItemInserted(val position: Int) : Event() class ItemRemoved(val position: Int) : Event() } } -
Copyright © Sansan, Inc. All rights reserved. > ObservableArray interface
ObservableArray<T> { val size: Int operator fun get(index: Int): T fun updates(): Observable<Event> sealed class Event { class DataSetChanged : Event() class ItemChanged(val position: Int) : Event() class ItemInserted(val position: Int) : Event() class ItemRemoved(val position: Int) : Event() } } operator overloadで array[0] という形のアクセスが可能 -
Copyright © Sansan, Inc. All rights reserved. > ObservableArray interface
ObservableArray<T> { val size: Int operator fun get(index: Int): T fun updates(): Observable<Event> sealed class Event { class DataSetChanged : Event() class ItemChanged(val position: Int) : Event() class ItemInserted(val position: Int) : Event() class ItemRemoved(val position: Int) : Event() } } 変更の通知を受け取ることが可能 -
Copyright © Sansan, Inc. All rights reserved. > ObservableArray interface
ObservableArray<T> { val size: Int operator fun get(index: Int): T fun updates(): Observable<Event> sealed class Event { class DataSetChanged : Event() class ItemChanged(val position: Int) : Event() class ItemInserted(val position: Int) : Event() class ItemRemoved(val position: Int) : Event() } } sealed classで複数のEventを定義 -
Copyright © Sansan, Inc. All rights reserved. > ArrayListを使った実装 class
ObservableArrayList<T>( private val arrayList: ArrayList<T> ) : ObservableArray<T> { private val updateSubject = PublishSubject.create<Event>() override val size: Int get() = arrayList.size override fun get(index: Int): T = arrayList[index] override fun updates() = updateSubject fun add(index: Int, elem: T) { arrayList.add(index, elem) updateSubject.onNext(Event.ItemInserted(index)) } -
Copyright © Sansan, Inc. All rights reserved. > ArrayListを使った実装 class
ObservableArrayList<T>( private val arrayList: ArrayList<T> ) : ObservableArray<T> { private val updateSubject = PublishSubject.create<Event>() override val size: Int get() = arrayList.size override fun get(index: Int): T = arrayList[index] override fun updates() = updateSubject fun add(index: Int, elem: T) { arrayList.add(index, elem) updateSubject.onNext(Event.ItemInserted(index)) } VQEBUFT 1VCMJTI4VCKFDUͰ࣮ -
Copyright © Sansan, Inc. All rights reserved. > ArrayListを使った実装 class
ObservableArrayList<T>( private val arrayList: ArrayList<T> ) : ObservableArray<T> { private val updateSubject = PublishSubject.create<Event>() override val size: Int get() = arrayList.size override fun get(index: Int): T = arrayList[index] override fun updates() = updateSubject fun add(index: Int, elem: T) { arrayList.add(index, elem) updateSubject.onNext(Event.ItemInserted(index)) } ཁૉͷՃ࣌ʹ*UFN*OTFSUFEΠϕϯτΛ ͛Δ -
Copyright © Sansan, Inc. All rights reserved. > operatorを拡張関数で追加 operator
fun <T> ObservableArray<T>.plus(other: ObservableArray<T>) : ObservableArray<T>{ /* .... */ } -
Copyright © Sansan, Inc. All rights reserved. > operatorを拡張関数で追加 operator
fun <T> ObservableArray<T>.plus(other: ObservableArray<T>) : ObservableArray<T>{ /* .... */ } // plusϝιουͰ + ԋࢉࢠͷ࣮Λஔ͖͑Δ val array1: ObservableArray<String>() val array2: ObservableArray<String>() val array3 = array1 + array2 // ࿈݁ -
Copyright © Sansan, Inc. All rights reserved. > operator fun
plus()の実装 operator fun <T> ObservableArray<T>.plus(other: ObservableArray<T>) : ObservableArray<T> = object : ObservableArray<T> { override val size: Int get() = [email protected] + other.size override fun get(index: Int): T = if (index < [email protected]) { this@plus[index] } else { other[index - [email protected]] } override fun updates(): Observable<Event> { ... } } -
Copyright © Sansan, Inc. All rights reserved. > operator fun
plus()の実装 operator fun <T> ObservableArray<T>.plus(other: ObservableArray<T>) : ObservableArray<T> = object : ObservableArray<T> { override val size: Int get() = [email protected] + other.size override fun get(index: Int): T = if (index < [email protected]) { this@plus[index] } else { other[index - [email protected]] } override fun updates(): Observable<Event> { ... } } ৽͍͠ແ໊ΫϥεΛੜ -
Copyright © Sansan, Inc. All rights reserved. > operator fun
plus()の実装 operator fun <T> ObservableArray<T>.plus(other: ObservableArray<T>) : ObservableArray<T> = object : ObservableArray<T> { override val size: Int get() = [email protected] + other.size override fun get(index: Int): T = if (index < [email protected]) { this@plus[index] } else { other[index - [email protected]] } override fun updates(): Observable<Event> { ... } } 2ͭͷarrayͷsizeΛ͢ -
Copyright © Sansan, Inc. All rights reserved. > operator fun
plus()の実装 operator fun <T> ObservableArray<T>.plus(other: ObservableArray<T>) : ObservableArray<T> = object : ObservableArray<T> { override val size: Int get() = [email protected] + other.size override fun get(index: Int): T = if (index < [email protected]) { this@plus[index] } else { other[index - [email protected]] } override fun updates(): Observable<Event> { ... } } 2ͭͷarray͔ΒelementͷऔಘઌΛ ৼΓ͚Δ -
Copyright © Sansan, Inc. All rights reserved. > operator fun
plus()の実装 operator fun <T> ObservableArray<T>.plus(other: ObservableArray<T>) : ObservableArray<T> = object : ObservableArray<T> { override val size: Int get() = [email protected] + other.size override fun get(index: Int): T { … } override fun updates(): Observable<Event> = Observable.merge( [email protected](), other.updates().map { val offset = [email protected] when (it) { is Event.DataSetChanged -> it is Event.ItemChanged -> Event.ItemChanged(it.position + offset) is Event.ItemInserted -> Event.ItemInserted(it.position + offset) is Event.ItemRemoved -> Event.ItemRemoved(it.position + offset) } } ) } -
Copyright © Sansan, Inc. All rights reserved. > operator fun
plus()の実装 operator fun <T> ObservableArray<T>.plus(other: ObservableArray<T>) : ObservableArray<T> = object : ObservableArray<T> { override val size: Int get() = [email protected] + other.size override fun get(index: Int): T { … } override fun updates(): Observable<Event> = Observable.merge( [email protected](), other.updates().map { val offset = [email protected] when (it) { is Event.DataSetChanged -> it is Event.ItemChanged -> Event.ItemChanged(it.position + offset) is Event.ItemInserted -> Event.ItemInserted(it.position + offset) is Event.ItemRemoved -> Event.ItemRemoved(it.position + offset) } } ) } 2ͭͷarray͔Βͷupdates()Λ merge -
Copyright © Sansan, Inc. All rights reserved. > operator fun
plus()の実装 operator fun <T> ObservableArray<T>.plus(other: ObservableArray<T>) : ObservableArray<T> = object : ObservableArray<T> { override val size: Int get() = [email protected] + other.size override fun get(index: Int): T { … } override fun updates(): Observable<Event> = Observable.merge( [email protected](), other.updates().map { val offset = [email protected] when (it) { is Event.DataSetChanged -> it is Event.ItemChanged -> Event.ItemChanged(it.position + offset) is Event.ItemInserted -> Event.ItemInserted(it.position + offset) is Event.ItemRemoved -> Event.ItemRemoved(it.position + offset) } } ) } ޙΖͷarray͔ΒͷupdateͰ indexΛͣΒ͢ -
Copyright © Sansan, Inc. All rights reserved. > ObservableArray interface
ObservableArray<T> { val size: Int operator fun get(index: Int): T fun updates(): Observable<Event> sealed class Event { class DataSetChanged : Event() class ItemChanged(val position: Int) : Event() class ItemInserted(val position: Int) : Event() class ItemRemoved(val position: Int) : Event() } } -
Copyright © Sansan, Inc. All rights reserved. > Eightでの使っているところ 30
ユーザー通知⽤ Item オンメモリ 投稿⽤ Item (固定) フィード表⽰⽤ Item Realm それぞれをObservableArrayとして それを合成 -
Copyright © Sansan, Inc. All rights reserved. > 公開してます -
本体の実装は50⾏! - https://github.com/yamamotoj/ObservableArray -
Copyright © Sansan, Inc. All rights reserved. > IcePick class
ExampleActivity extends Activity { @State String username; // This will be automatically saved and restored @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Icepick.restoreInstanceState(this, savedInstanceState); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Icepick.saveInstanceState(this, outState); } // You can put the calls to Icepick into a BaseActivity // All Activities extending BaseActivity automatically have state saved/restored } ͜ΕΛKotlinͷػೳΛ͔࣮ͭͬͯͯ͠Έͨ -
Copyright © Sansan, Inc. All rights reserved. > Pikkel class
MainActivity : Activity(), Pikkel by PikkelDelegate() { var data by state<String?>(null) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) restoreInstanceState(savedInstanceState) } override fun onSaveInstanceState(outState: Bundle?) { super.onSaveInstanceState(outState) saveInstanceState(outState) } } ͓·͡ͳ͍ -
Copyright © Sansan, Inc. All rights reserved. class MainActivity :
Activity(), Pikkel by PikkelDelegate() { var data by state<String?>(null) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) restoreInstanceState(savedInstanceState) } override fun onSaveInstanceState(outState: Bundle?) { super.onSaveInstanceState(outState) saveInstanceState(outState) } } อଘ͍ͨ͠ϓϩύςΟΛ by state<T>() ͷ delegated propertyͰࢦఆ -
Copyright © Sansan, Inc. All rights reserved. class MainActivity :
Activity(), Pikkel by PikkelDelegate() { var data by state<String?>(null) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) restoreInstanceState(savedInstanceState) } override fun onSaveInstanceState(outState: Bundle?) { super.onSaveInstanceState(outState) saveInstanceState(outState) } } onSaveInstanceState() Ͱstate()ࢦఆ͍ͯͨ͠ϓϩύ ςΟ͕ࣗಈతʹอଘ͞ΕΔ -
Copyright © Sansan, Inc. All rights reserved. class MainActivity :
Activity(), Pikkel by PikkelDelegate() { var data by state<String?>(null) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) restoreInstanceState(savedInstanceState) } override fun onSaveInstanceState(outState: Bundle?) { super.onSaveInstanceState(outState) saveInstanceState(outState) } } ʢ͠อଘͯ͋͠Εʣ onCreate()ͷ savedInstanceState͔ΒΛ ෮ݩ -
Copyright © Sansan, Inc. All rights reserved. > 公開しています。 -
本体の実装は64⾏! - https://github.com/yamamotoj/Pikkel