Kotlinの言語機能をフル活用したAndroidアプリの開発

 Kotlinの言語機能をフル活用したAndroidアプリの開発

Hatena Engineer Seminar #9 で発表した内容です

E28404a128b6014e6f499d2a967c72a0?s=128

Takuji Nishibayashi

October 30, 2017
Tweet

Transcript

  1. 3.

    ࣗݾ঺հ • ੢ྛ ୓ࢤ (ʹ͠͹΍͠ ͨ͘͡) • (hatena | twitter

    | github) takuji31 • גࣜձࣾ͸ͯͳ ΞϓϦέʔγϣϯΤϯδχΞ • ϒοΫϚʔΫΞϓϦνʔϜॴଐ
  2. 19.
  3. 20.
  4. 30.

    Javaͷmodel(Ұ෦) public class JavaUser { private final long id; private

    String firstName; private String lastName; private String profile; private boolean registered; public JavaUser(long id, String firstName, String lastName, String profile, boolean registered) { this.id = id; this.firstName = firstName; this.lastName = lastName; this.profile = profile; this.registered = registered; } public long getId() { return id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getProfile() { return profile; } public void setProfile(String profile) { this.profile = profile; } public boolean isRegistered() { return registered; } public void setRegistered(boolean registered) { this.registered = registered; } public String getFullName() { return firstName + " " + lastName; } }
  5. 31.
  6. 32.

    Kotlinͷmodel data class JavaUser( val id: Long, var firstName: String,

    var lastName: String, var profile: String?, var isRegistered: Boolean = false ) { val fullName: String get() = firstName + " " + lastName } ಄ʹEBUB Λ͚ͭΔ શͯͷ CBDLJOHpFME ϓϩύςΟʔΛ DPOTUSVDUPSͰఆٛ
  7. 35.
  8. 38.

    FragmentΛ֦ுϓϩύςΟʔͰ ֦ு͢Δ val Fragment.baseActivity: BaseActivity?
 get() = activity as BaseActivity?


    val Fragment.actionBar: ActionBar?
 get() = baseActivity?.supportActionBar ֦ு͍ͨ͠ܕ Λॻ͘ ͦͷଞ͸௨ৗͷ ϓϩύςΟʔͱಉ͡
  9. 39.

    RealmͷProviderΛ֦ுؔ਺Ͱ ֦ு͢Δ fun Provider<Realm>.getAutoCloseObservable(): Observable<Realm> { val realm = get()

    realm.use { return Observable.create { emitter -> val instance = get() emitter.setCancellable { instance.close() } emitter.onNext(instance) } } } ֦ு͍ͨ͠ܕ Λॻ͘ ͦͷଞ͸௨ৗͷ ؔ਺ͱಉ͡ (FOFSJDTͷ ܕύϥϝʔλʔ΋ࢦఆՄ
 ϓϩύςΟʔ΋ಉ༷
  10. 53.

    Delegated propertyͷఆٛ open class BaseObservableProperty<T : Any?>( vararg val propertyId:

    Int, var value: T ) : ReadWriteProperty<BaseObservable, T> { override fun getValue( thisRef: BaseObservable, property: KProperty<*>): T { return value } override fun setValue( thisRef: BaseObservable, property: KProperty<*>, value: T) { this.value = value propertyId.forEach(thisRef::notifyPropertyChanged) } } 3FBE8SJUF1SPQFSUZ ΠϯλʔϑΣΠεΛ࣮૷ HFU7BMVFTFU7BMVFΛ ఆٛ UIJTͷࢀরͱQSPQFSUZͷ ৘ใ͕౉͞ΕΔ
  11. 54.

    Delegated propertyͷఆٛ class NonNullBaseObservableProperty<T : Any>(vararg propertyId: Int, value: T)

    : BaseObservableProperty<T>(propertyId = *propertyId, value = value) fun <T : Any?> BaseObservable.property(vararg propertyId: Int, value: T? = null) = BaseObservableProperty(propertyId = *propertyId, value = value) fun <T : Any> BaseObservable.nonNullProperty(vararg propertyId: Int, value: T) = NonNullBaseObservableProperty(propertyId = *propertyId, value = value) ܕ͕/PO/VMMͳ΋ͷ༻ͷఆٛ ֦ுؔ਺ʹ͓ͯ͘͠ͱ ࢖͏࣌ʹศར
  12. 55.

    ར༻͢Δ class ViewModel: BaseObservable() { @get:Bindable var users: List<User> by

    nonNullProperty(BR.users, value = emptyList()) fun requestUsers(): Disposable { return getUser .execute() .subscribeBy( onSuccess = { user -> this.users = users }, ) } } CZͷޙʹΦϒδΣΫτΛ౉͢ TFU͢Δ͜ͱͰࣗಈతʹ OPUJGZ1SPQFSUZ$IBOHFE͕ ݺ͹ΕΔ
  13. 61.

    σϑΥϧτͷ Delegated property(Ұ෦) • Delegates.notNull • not-null͕ͩॳظԽ࣌ʹॳظԽͰ͖ͳ͍ϓϩύςΟʔ • nullͷ··ΞΫηεͨ͠Βྫ֎ •

    lazy • ஗ԆॳظԽ • ࠷ॳͷΞΫηε࣌ʹҾ਺Ͱ౉ͨ͠ϒϩοΫͷ໭Γ஋Λฦͯ͠ Ωϟογϡ͢Δ