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

Androidエンジニアが1人という不安と向き合う

rmakiyama
October 19, 2021

 Androidエンジニアが1人という不安と向き合う

▼動画URL
https://youtu.be/5M0xJLdAcAE

▼Android Kotlin Fundamentalsについて
Android Basics in Kotlinのアップデートに伴い、提供が終了されます。
これからはアップデートされたAndroid Basics in Kotlinで基礎を学ぶのが良さそうです。
詳しくはAndroid Developers Blogをご参照ください。
https://android-developers.googleblog.com/2022/01/android-basics-and-training-update.html

---
Androidエンジニア不足が叫ばれる昨今、1つのAndroidアプリに対して1人のAndroidエンジニアという状況が増えてきているように感じています。このような状況下では、スキル面・キャアリア面での不安を持つ方も多いのではないでしょうか。牧山のキャリアとしても、ほとんどがチームにAndroidエンジニアが1人という経歴です。
本セッションでは、その経験を踏まえ、牧山自身が抱えてきた不安を元に、その不安に向き合うためにやったこと・やっていることについて話します。

▼ アジェンダ

技術の学び方を身につける
優れたソースコードを読む
ソフトウェア開発を学ぶ
サービスへの理解を深める
エンジニアリングでサービスを前に進める

rmakiyama

October 19, 2021
Tweet

More Decks by rmakiyama

Other Decks in Technology

Transcript

  1. "OESPJEΤϯδχΞ͕
    ਓͱ͍͏ෆ҆ͱ޲͖߹͏
    3ZP.BLJZBNBSNBLJZBNB
    3BEJPUBML*OD
    !%SPJE,BJHJ%BZ

    View Slide

  2. w ຀ࢁྎ
    w 3BEJPUBMLגࣜձࣾ
    w "OESPJEΤϯδχΞ
    [email protected]
    wSNBLJZBNB
    ࣗݾ঺հ

    View Slide

  3. "OESPJE։ൃܦݧ
    w ೥ΤΩαΠτגࣜձࣾʹ৽ଔೖࣾ
    w ೥d৽ن"OESPJEΞϓϦ։ൃ
    w ೥d3BEJPUBMLΞϓϦϑϧϦχϡʔΞϧ
    w ೥3BEJPUBMLגࣜձࣾʹస੶
    w Ҿ͖ଓ͖3BEJPUBMLΞϓϦ։ൃ

    View Slide

  4. ˝ "OESPJEνʔϜ
    ˝ ձࣾͷ"OESPJEFS
    ೥৽ن"OESPJEΞϓϦ։ൃ
    "OESPJE։ൃܦݧ

    View Slide

  5. ˝ "OESPJEνʔϜ
    ˝ ձࣾͷ"OESPJEFS
    ೥3BEJPUBMLΞϓϦϑϧϦχϡʔΞϧ
    "OESPJE։ൃܦݧ

    View Slide

  6. ˝ "OESPJEνʔϜ
    ˝ ձࣾͷΤϯδχΞ
    J044FSWFS໊֤
    ೥3BEJPUBMLגࣜձࣾʹస੶
    "OESPJE։ൃܦݧ

    View Slide

  7. ˝ "OESPJEνʔϜ
    "OESPJE։ൃܦݧ
    ೥3BEJPUBMLגࣜձࣾ

    View Slide

  8. ΩϟϦΞͷ΄ͱΜͲ͕
    νʔϜʹ"OESPJEΤϯδχΞ͕ͻͱΓ

    View Slide

  9. ͜Ε·Ͱʹ๊͖͑ͯͨෆ҆
    w "OESPJEΤϯδχΞͱͯ͠ͷεΩϧෆ଍
    w ૬ஊ૬खɺϩʔϧϞσϧ͕͍ͳ͍
    w ͜ͷΞʔΩςΫνϟͰ߹͍ͬͯΔͷʜʁ
    w ͜Ε͔Β΋"OESPJEຊͰେৎ෉ͳͷ͔ʁ

    View Slide

  10. ෆ҆͸ͳ͘ͳΒͳ͍΋ͷ
    w ෆ҆͸༷ʑͳཁҼͰҾ͖ى͜͞ΕΔ
    w ٕज़ͷਐาɺςΫϊϩδʔͷਐԽ
    w ୲౰͍ͯ͠ΔαʔϏεͷ੒௕
    w ձࣾ૊৫ͷมԽ
    w ϥΠϑεςʔδͷมԽ
    w FUDʜ

    View Slide

  11. ෆ҆ͱ޲͖߹͏͜ͱ͕େࣄ

    View Slide

  12. ࢲ͕ෆ҆ͱ޲͖߹͏ͨΊʹ΍ͬͨ͜ͱ
    w ٕज़ͷֶͼํΛ਎ʹ͚ͭΔ
    w ༏ΕͨιʔείʔυΛಡΉ
    w ιϑτ΢ΣΞ։ൃΛֶͿ
    w αʔϏε΁ͷཧղΛਂΊΔ
    w ΤϯδχΞϦϯάͰαʔϏεΛલʹ͢͢ΊΔ
    ΞδΣϯμ

    View Slide

  13. ٕज़ͷֶͼํΛ਎ʹ͚ͭΔ

    View Slide

  14. ٕज़ͷֶͼํΛ਎ʹ͚ͭΔ
    w ࣮ݱ͍ͨ͠ίʔυΛॻ͚ΔΑ͏ʹͳΔ·Ͱ
    w ܧଓతͳΩϟονΞοϓΛ͢Δ
    "OESPJEΤϯδχΞͱͯ͠

    View Slide

  15. ࣮ݱ͍ͨ͠ίʔυΛॻ͚ΔΑ͏ʹͳΔ·Ͱ
    w ॻ੶Λ࡭΍Γ͖Δ
    w DPEFMBCνϡʔτϦΞϧΛ΍Δ
    w ࣮຿ͰΨϯΨϯ஁͑ͯ΋Β͏
    w ཉ͍͠ΞϓϦΛ࡞ֶͬͯͿ
    w FUDʜ
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔ

    View Slide

  16. ࣮ݱ͍ͨ͠ίʔυΛॻ͚ΔΑ͏ʹͳΔ·Ͱ
    w ॻ੶Λ࡭΍Γ͖Δ
    w DPEFMBCνϡʔτϦΞϧΛ΍Δ
    w ࣮຿ͰΨϯΨϯ஁͑ͯ΋Β͏
    w ཉ͍͠ΞϓϦΛ࡞ֶͬͯͿ
    w FUDʜ
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔ
    ࣗ෼ʹ߹͏ํ๏Λ໛ࡧ͠Α͏🙌

    View Slide

  17. ࠓͩͬͨΒ͜Ε͕Φεεϝ
    w "OESPJE#BTJDTJO,PUMJO
    w %FWFMPQJOH"OESPJE"QQTXJUI,PUMJO

    CZ(PPHMF
    w "OESPJE,PUMJO'VOEBNFOUBMT
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔ࣮ݱ͍ͨ͠ίʔυΛॻ͚ΔΑ͏ʹͳΔ

    View Slide

  18. "OESPJE#BTJDTJO,PUMJO
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔ࣮ݱ͍ͨ͠ίʔυΛॻ͚ΔΑ͏ʹͳΔΦεεϝ
    IUUQTEFWFMPQFSBOESPJEDPNDPVSTFTBOESPJECBTJDTLPUMJODPVSTF

    View Slide

  19. "OESPJE#BTJDTJO,PUMJO
    w ,PUMJO"OESPJEͷجຊ͔Βֶ΂Δ
    w ಈը΍$PEFMBC͔ΒͳΔ1BUIXBZΛ࣮ࢪ
    w +FUQBDL΋ؚ·ΕΔ
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔ࣮ݱ͍ͨ͠ίʔυΛॻ͚ΔΑ͏ʹͳΔΦεεϝ

    View Slide

  20. %FWFMPQJOH"OESPJE"QQTXJUI,PUMJOCZ(PPHMF
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔ࣮ݱ͍ͨ͠ίʔυΛॻ͚ΔΑ͏ʹͳΔΦεεϝ
    IUUQTXXXVEBDJUZDPNDPVSTFEFWFMPQJOHBOESPJEBQQTXJUILPUMJOVE

    View Slide

  21. %FWFMPQJOH"OESPJE"QQTXJUI,PUMJOCZ(PPHMF
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔ࣮ݱ͍ͨ͠ίʔυΛॻ͚ΔΑ͏ʹͳΔΦεεϝ
    w ແྉ
    w ׬ྃ·Ͱͷ૝ఆظؒ͸໿ϲ݄
    w εΩϧϨϕϧ͸தڃ·ͰΛ૝ఆ
    w ϕετϓϥΫςΟεɺϞμϯͳઃܭ

    View Slide

  22. "OESPJE,PUMJO'VOEBNFOUBMT
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔ࣮ݱ͍ͨ͠ίʔυΛॻ͚ΔΑ͏ʹͳΔΦεεϝ
    IUUQTEFWFMPQFSBOESPJEDPNDPVSTFTLPUMJOBOESPJEGVOEBNFOUBMTPWFSWJFX

    View Slide

  23. "OESPJE,PUMJO'VOEBNFOUBMT
    w $PEFMBC͕த৺
    w +FUQBDL,PUMJO$PSPVUJOFT
    w 3FQPTJUPSZύλʔϯʹ͍ͭͯͷϨοεϯ΋͋Δ
    w ΞϓϦΞʔΩςΫνϟΨΠυʹଇ͍ͯ͠Δ
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔ࣮ݱ͍ͨ͠ίʔυΛॻ͚ΔΑ͏ʹͳΔΦεεϝ

    View Slide

  24. ׬શʹཧղͨ͠💪

    View Slide

  25. ׬શʹཧղͨ͠🤔

    View Slide

  26. ΩϟονΞοϓ͠ଓ͚Δඞཁ͕͋Δ
    w ৽͍ٕ͠ज़͕ͲΜͲΜग़ͯ͘Δ
    w ,PUMJO$PSPVUJOFT'MPXT
    w +FUQBDL$PNQPTF
    w FUDʜ
    w ϕετϓϥΫςΟε΋มΘΔ
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔ

    View Slide

  27. ΩϟονΞοϓͷํ๏͸༷ʑ
    w ެࣜυΩϡϝϯτ
    w "OESPJE%FWFMPQFST#MPH
    w 1SP"OESPJE%FW
    w 5FDI#PPTUFS
    w "OESPJE%BHBTIJ"OESPJE8BHBTIJ
    w 5XJUUFSͰ"OESPJEΤϯδχΞΛϑΥϩʔ
    w FUDʜ
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔܧଓతͳΩϟονΞοϓ

    View Slide

  28. ΩϟονΞοϓͷํ๏͸༷ʑ
    w ެࣜυΩϡϝϯτ
    w "OESPJE%FWFMPQFST#MPH
    w 1SP"OESPJE%FW
    w 5FDI#PPTUFS
    w "OESPJE%BHBTIJ"OESPJE8BHBTIJ
    w 5XJUUFSͰ"OESPJEΤϯδχΞΛϑΥϩʔ
    w FUDʜ
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔܧଓతͳΩϟονΞοϓ
    ࣗ෼ʹ߹͏ํ๏Λ໛ࡧ͠Α͏🙌

    View Slide

  29. ΩϟονΞοϓͷํ๏͸༷ʑ
    wެࣜυΩϡϝϯτ
    w "OESPJE%FWFMPQFST#MPH
    w 1SP"OESPJE%FW
    w 5FDI#PPTUFS
    w "OESPJE%BHBTIJ"OESPJE8BHBTIJ
    w 5XJUUFSͰ"OESPJEΤϯδχΞΛϑΥϩʔ
    w FUDʜ
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔܧଓతͳΩϟονΞοϓ

    View Slide

  30. ެࣜυΩϡϝϯτ
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔܧଓతͳΩϟονΞοϓ
    IUUQTEFWFMPQFSBOESPJEDPNKFUQBDLBOESPJEYFYQMPSFS

    View Slide

  31. ެࣜυΩϡϝϯτ
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔܧଓతͳΩϟονΞοϓ
    IUUQTEFWFMPQFSBOESPJEDPNKFUQBDLBOESPJEYSFMFBTFTGSBHNFOU

    View Slide

  32. ެࣜυΩϡϝϯτ
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔܧଓతͳΩϟονΞοϓ
    IUUQTEFWFMPQFSBOESPJEDPNKFUQBDLBOESPJEYSFMFBTFTGSBHNFOU

    View Slide

  33. ެࣜυΩϡϝϯτ
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔܧଓతͳΩϟονΞοϓ
    IUUQTEFWFMPQFSBOESPJEDPNKFUQBDLBOESPJEYSFMFBTFTGSBHNFOU

    View Slide

  34. ެࣜυΩϡϝϯτ
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔܧଓతͳΩϟονΞοϓ
    IUUQTEFWFMPQFSBOESPJEDPNKFUQBDLBOESPJEYSFMFBTFTGSBHNFOU

    View Slide

  35. ެࣜυΩϡϝϯτ
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔܧଓతͳΩϟονΞοϓ
    IUUQTEFWFMPQFSBOESPJEDPNHVJEFGSBHNFOUT

    View Slide

  36. ެࣜυΩϡϝϯτ
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔܧଓతͳΩϟονΞοϓ
    IUUQTEFWFMPQFSBOESPJEDPNHVJEFGSBHNFOUT

    View Slide

  37. ެࣜυΩϡϝϯτ
    w +FUQBDL܈͸ಛʹॆ࣮͍ͯ͠Δ
    w ϢʔβʔΨΠυ΍ίʔυϥϘ΁ͷಈઢ΋͋Δ
    w ೔ຊޠͰ΋݁ߏॆ࣮͍ͯ͠Δ
    w ӳޠͷυΩϡϝϯτͱࠩҟ͕͋Δ͜ͱ΋ʜ
    w 63-ʹ IMFOΛ͚ͭͯݟΔบ͸͚ͭΔͱྑ͍
    ٕज़ͷֶͼํΛ਎ʹ͚ͭΔܧଓతͳΩϟονΞοϓ

    View Slide

  38. ༏ΕͨιʔείʔυΛಡΉ

    View Slide

  39. ͳͥιʔείʔυΛಡΉͷ͔
    w ίʔυΛಡΉྗ͸ͣͬͱ׆͖Δ
    w ࣮຿Ͱ΋ίʔυΛಡΉ࣌ؒ͸ඇৗʹ௕͍
    w ίʔυϨϏϡʔ΋ͦͷҰ؀
    w ઌਓͷ஌ܙ͔Βֶ΂Δ
    w νʔϜ΍ձࣾͷ֎͔ΒֶͿ
    w ࣮ݱ͢Δํ๏ͷΠϯσοΫεΛ૿΍͢
    ༏ΕͨιʔείʔυΛಡΉ

    View Slide

  40. "OESPJEͰΦεεϝͷ044
    w BOESPJETVO
    fl
    PXFS
    w HPPHMFJPTDIFE
    w OJDLCVUDIFSQMBJE
    w %SPJE,BJHJDPOGFSFODFBQQ
    w ESPJELOJHIUT%SPJE,[email protected]"QQ
    w BOESPJEUSBDLS
    w BOESPJEBSDIJUFDUVSFDPNQPOFOUTTBNQMFT
    w DISJTCBOFTUJWJ
    w TLZEPWFT1PLFEFY
    w FUDʜ
    ༏ΕͨιʔείʔυΛಡΉ
    ʜ(JU)VC4UBSˑL
    ʜ(JU)VC4UBSˑL
    ʜ(JU)VC4UBSˑL
    ʜ(JU)VC4UBSˑ
    ʜ(JU)VC4UBSˑ
    ʜ(JU)VC4UBSˑ
    ʜ(JU)VC4UBSˑL
    ʜ(JU)VC4UBSˑL
    ʜ(JU)VC4UBSˑL

    View Slide

  41. ಡΉͱ͖ͷίπ
    w ಡΉ໨తΛܾΊΔ
    w είʔϓΛߜͬͯಡΉ
    w ෳ਺ͷιʔείʔυΛࢀর͢Δ
    w ࠷ޙʹࣗ਎ͷϓϩμΫτͱൺֱ͢Δ
    w എܠɾҙਤΛ૝૾ͯ͠ΈΔ
    ༏ΕͨιʔείʔυΛಡΉ

    View Slide

  42. 👀ಡΜͰΈΑ͏🔍

    View Slide

  43. ಡΜͰΈΑ͏
    w ໨త7JFX.PEFMͷ࣮૷ํ਑Λࢀߟʹ͢Δ
    w DPOGFSFODFBQQͱUJWJ
    ༏ΕͨιʔείʔυΛಡΉ

    View Slide

  44. %SPJE,BJHJDPOGFSFODFBQQ
    w %SPJE,BJHJͷެࣜΞϓϦ
    w ίϯτϦϏϡʔλʔେ׻ܴ
    w νϟϨϯδΛ੝ΓࠐΜͩઃܭ
    w 5IJTBQQIBOEMFTUIF7JFX.PEFMXJUIBO.7*
    MJLFJOUFSGBDF
    ༏ΕͨιʔείʔυΛಡΉ

    View Slide

  45. DPOGFSFODFBQQ3FBM'FFE7JFX.PEFMLU
    @HiltViewModel

    class RealFeedViewModel @Inject constructor(

    private val repository: FeedRepository,

    ) : ViewModel(), FeedViewModel {

    private val effectChannel = …

    private val showProgressLatch = …

    override val effect: Flow = …

    init {…}

    private val allFeedContents: StateFlow>>


    private val filters: MutableStateFlow = MutableStateFlow(Filters())

    override val state: StateFlow

    override fun event(event: FeedViewModel.Event) {

    viewModelScope.launch {

    @Exhaustive

    when (event) {…}

    }

    }

    private suspend fun refreshRepository() {…}

    }

    IUUQTHJUIVCDPN%SPJE,BJHJDPOGFSFODFBQQ

    View Slide

  46. DPOGFSFODFBQQ3FBM'FFE7JFX.PEFMLU
    @HiltViewModel

    class RealFeedViewModel @Inject constructor(

    private val repository: FeedRepository,

    ) : ViewModel(), FeedViewModel {

    private val effectChannel = …

    private val showProgressLatch = …

    override val effect: Flow = …

    init {…}

    private val allFeedContents: StateFlow>>


    private val filters: MutableStateFlow = MutableStateFlow(Filters())

    override val state: StateFlow

    override fun event(event: FeedViewModel.Event) {

    viewModelScope.launch {

    @Exhaustive

    when (event) {…}

    }

    }

    private suspend fun refreshRepository() {…}

    }

    interface FeedViewModel : UnidirectionalViewModel {

    data class State(

    val showProgress: Boolean = false,

    val filters: Filters = Filters(),

    val filteredFeedContents: FeedContents = FeedContents(),

    )

    sealed class Effect {…}

    sealed class Event {…}

    override val state: StateFlow

    override val effect: Flow

    override fun event(event: Event)

    }

    IUUQTHJUIVCDPN%SPJE,BJHJDPOGFSFODFBQQ

    View Slide

  47. DPOGFSFODFBQQ3FBM'FFE7JFX.PEFMLU
    @HiltViewModel

    class RealFeedViewModel @Inject constructor(

    private val repository: FeedRepository,

    ) : ViewModel(), FeedViewModel {

    private val effectChannel = …

    private val showProgressLatch = …

    override val effect: Flow = …

    init {…}

    private val allFeedContents: StateFlow>>


    private val filters: MutableStateFlow = MutableStateFlow(Filters())

    override val state: StateFlow

    override fun event(event: FeedViewModel.Event) {

    viewModelScope.launch {

    @Exhaustive

    when (event) {…}

    }

    }

    private suspend fun refreshRepository() {…}

    }

    interface FeedViewModel : UnidirectionalViewModel {

    data class State(

    val showProgress: Boolean = false,

    val filters: Filters = Filters(),

    val filteredFeedContents: FeedContents = FeedContents(),

    )

    sealed class Effect {…}

    sealed class Event {…}

    override val state: StateFlow

    override val effect: Flow

    override fun event(event: Event)

    }

    interface UnidirectionalViewModel {

    val state: StateFlow

    val effect: Flow

    fun event(event: EVENT)

    }

    IUUQTHJUIVCDPN%SPJE,BJHJDPOGFSFODFBQQ

    View Slide

  48. %SPJE,BJHJDPOGFSFODFBQQ
    w ΠϯλϑΣʔεʹΑΔద੾ͳ੍໿
    w ଟ͘ͷίϯτϦϏϡʔλͰͷ։ൃΛ

    ҙ͍ࣝͯ͠Δͱ͍͏ҙਤΛײ͡Δ
    ༏ΕͨιʔείʔυΛಡΉ

    View Slide

  49. DISJTCBOFTUJWJ
    w 5JWJJTBXPSLJOQSPHSFTT57TIPXUSBDLJOH
    "OESPJEBQQ XIJDIDPOOFDUTUP5SBLUUW
    w 5JWJJTBOBQQUIBUBUUFNQUTUPVTFUIFMBUFTU
    DVUUJOHFEHFMJCSBSJFTBOEUPPMT
    w ׂҎ্ΛDISJTCBOFTࢯ͕։ൃ
    ༏ΕͨιʔείʔυΛಡΉ

    View Slide

  50. DISJTCBOFTUJWJ3FBM'FFE7JFX.PEFMLU
    @HiltViewModel

    internal class ShowDetailsViewModel @Inject constructor(

    savedStateHandle: SavedStateHandle,

    private val updateShowDetails: UpdateShowDetails,



    ) : ViewModel() {



    private val pendingActions = MutableSharedFlow()



    val uiEffects: Flow get() = _uiEffects.asSharedFlow()

    val state = combine(…) {…}

    init {

    viewModelScope.launch {

    pendingActions.collect { action
    ->


    when (action) {



    }

    }

    }



    }



    fun submitAction(action: ShowDetailsAction) {

    viewModelScope.launch { pendingActions.emit(action) }

    }



    }
    IUUQTHJUIVCDPNDISJTCBOFTUJWJ

    View Slide

  51. DISJTCBOFTUJWJ
    w ୯Ұํ޲ͷσʔλϑϩʔ
    w 7JFX.PEFMΛมߋ͠΍͍͢Α͏ʹ͍ͯ͠Δʁ
    w ""$ͷ7JFX.PEFMΛ௚઀ܧঝ
    w 6TF$BTF૚Λઃ͚ͯ7JFX.PEFMͷ੹຿Λബ͍ͯ͘͠Δ
    ༏ΕͨιʔείʔυΛಡΉ

    View Slide

  52. ࣗ਎ͷϓϩμΫτίʔυͱ
    ൺֱͯ͠Έ͍ͯͩ͘͞🔍

    View Slide

  53. ஫ҙΞʔΩςΫνϟʹ།Ұͷղ͸ͳ͍
    ༏ΕͨιʔείʔυΛಡΉ
    w ༷ʑͳཁҼʹΑͬͯมΘΔ
    w νʔϜͷϝϯόʔ
    w ϓϩμΫτͷಛੑ
    w ࠾༻͢Δٕज़
    w FUDʜ
    w Πϯλʔωοτʹ།Ұͷղ͸ͳ͍

    View Slide

  54. ΞʔΩςΫνϟʹ།Ұͷղ͸ͳ͍
    ༏ΕͨιʔείʔυΛಡΉ
    ࢀߟʰ%FTJHO*UϓϩάϥϚʔͷͨΊͷΞʔΩςΫςΟϯάೖ໳ʱQ

    View Slide

  55. ࣗ਎ͷϓϩμΫτͱ޲͖߹͑ΔΑ͏ʹͳΔ
    ༏ΕͨιʔείʔυΛಡΉΞʔΩςΫνϟʹ།Ұͷղ͸ͳ͍
    w ࢹ໺Λ޿͛ͯΞʔΩςΫνϟΛݟΕΔΑ͏ʹͳΔ
    w ϓϩμΫτΛ΋ͱʹϑΟʔυόοΫϧʔϓΛճ͢
    w ΠςϨʔγϣϯΛߴ଎ʹճ͍ͤͯΔ͔ʁ
    w ϘτϧωοΫʹͳ͍ͬͯΔ՝୊͸Ͳ͔͜ʁ
    w ςοΫϦʔυΞʔΩςΫτͱͯ͠ৼΔ෣͏

    View Slide

  56. "OESPJEຊ΁ͷෆ҆

    View Slide

  57. ෆ҆ͷछ͸ͻͱͦΕͧΕ
    "OESPJEຊ΁ͷෆ҆
    w "OESPJE։ൃҎ֎ͷεΩϧηοτ
    w "OESPJEͱ͍͏ٕज़΁ͷকདྷੑ
    w J04Ϣʔβʔ͕ϝΠϯλʔήοτͳαʔϏε
    w ΈΜͳ͕ෆ͕͍҆ͬͯΔͷͰࣗ෼΋ෆ҆ʜ
    w യવͱͨ͠ෆ҆

    View Slide

  58. มΘΓʹ͍͘΋ͷʹ໨Λ޲͚Δ
    w ιϑτ΢ΣΞͷݪཧݪଇ
    w ର৅ྖҬΛద੾ʹϞσϦϯά͢Δ͜ͱ
    w αʔϏεΛΑΓྑ͍͖͍ͯͨ͘͜͠ͱ
    "OESPJEຊ΁ͷෆ҆

    View Slide

  59. ࢲ͕ෆ҆ͱ޲͖߹͏ͨΊʹ΍ͬͨ͜ͱ
    w ٕज़ͷֶͼํΛ਎ʹ͚ͭΔ
    w ༏ΕͨιʔείʔυΛಡΉ
    w ιϑτ΢ΣΞ։ൃΛֶͿ
    w αʔϏε΁ͷཧղΛਂΊΔ
    w ΤϯδχΞϦϯάͰαʔϏεΛલʹ͢͢ΊΔ
    ΞδΣϯμ

    View Slide

  60. ιϑτ΢ΣΞ։ൃΛֶͿ

    View Slide

  61. ͳͥιϑτ΢ΣΞ։ൃʁ
    ιϑτ΢ΣΞ։ൃΛֶͿ
    w "OESPJE։ൃ͔Βιϑτ΢ΣΞ։ൃʹࢹ໺Λ޿͛Δ
    w "OESPJE։ൃʹؐݩͰ͖Δ΋ͷ͹͔Γ
    w ͢Ͱʹ࣮ફ͍ͯ͠Δ͜ͱ΋ଟ͍͜ͱʹؾͮ͘
    w Ͳ͏࣮૷͢Δ͔ɺ͔Βɺͳͥͦ͏࣮૷͢Δ͔΁
    w "OESPJEҎ֎ͷΤϯδχΞͱҰॹʹֶ΂Δ

    View Slide

  62. ҰൠతͳݪཧݪଇΛֶͿ
    ιϑτ΢ΣΞ։ൃΛֶͿ
    w ୯Ұ੹೚ͷݪଇ
    w ΦʔϓϯΫϩʔζυݪଇ
    w Ϧείϑͷஔ׵ݪଇ
    w ΠϯλϑΣʔε෼཭ͷݪଇ
    w ґଘੑٯసͷݪଇ
    w %3:ݪଇ
    w ,*44ͷݪଇ
    w :"(/*
    w ந৅ґଘݪଇ
    w ҆ఆґଘݪଇ
    w FUDʜ

    View Slide

  63. ؔ৺ͷ෼཭
    ιϑτ΢ΣΞ։ൃΛֶͿ
    w ࠷΋ॏཁͳݪଇͷ͏ͪͷͻͱͭ
    w ͋ΒΏΔιϑτ΢ΣΞ։ൃʹద༻Ͱ͖Δ
    w "OESPJE։ൃͱ΋ೃછΈਂ͍

    View Slide

  64. ΞϓϦΞʔΩςΫνϟΨΠυ
    ιϑτ΢ΣΞ։ൃΛֶͿؔ৺ͷ෼཭
    IUUQTEFWFMPQFSBOESPJEDPNKFUQBDLHVJEF IMKBTFQBSBUJPOPGDPODFSOT

    View Slide

  65. ΞϓϦͷਪ঑ΞʔΩςΫνϟ
    ιϑτ΢ΣΞ։ൃΛֶͿؔ৺ͷ෼཭
    w .77.ύλʔϯ
    w ϨΠϠʔυΞʔΩςΫνϟ
    w 6*૚ͱϞσϧ૚

    View Slide

  66. "DUJWJUZ'SBHNFOU
    ιϑτ΢ΣΞ։ൃΛֶͿؔ৺ͷ෼཭ΞϓϦͷਪ঑ΞʔΩςΫνϟ
    w 7JFX.PEFMͷΈʹґଘ
    w 6*ͷදࣔ
    w ΞϓϦίϯϙʔωϯτͱͷ

    ΍ΓͱΓ

    View Slide

  67. 7JFX.PEFM
    ιϑτ΢ΣΞ։ൃΛֶͿؔ৺ͷ෼཭ΞϓϦͷਪ঑ΞʔΩςΫνϟ
    w 3FQPTJUPSZͷΈʹґଘ
    w 6*ʹσʔλΛఏڙ
    w Ϟσϧͱͷ΍ΓͱΓ

    View Slide

  68. 3FQPTJUPSZ
    ιϑτ΢ΣΞ։ൃΛֶͿؔ৺ͷ෼཭ΞϓϦͷਪ঑ΞʔΩςΫνϟ
    w ӬଓσʔλϞσϧͱ

    ϦϞʔτιʔεʹґଘ
    w 7JFXͷ͜ͱΛ஌Βͳ͍

    View Slide

  69. େࣄͳͷ͸ؔ৺ͷ෼཭
    ιϑτ΢ΣΞ։ൃΛֶͿؔ৺ͷ෼཭
    w .77.΍ϨΠϠʔυ͸໨తͰ͸ͳ͘खஈ
    w lͳͥzͦΕΛ͢Δͷ͔͕େࣄ

    View Slide

  70. ؔ৺ͷ෼཭͕Ͱ͖͍ͯͳ͍ྫ
    ιϑτ΢ΣΞ։ൃΛֶͿؔ৺ͷ෼཭
    class MainFragment : Fragment(R.layout.main_fragment) {

    private val viewModel: MainViewModel by viewModels()

    override fun onViewCreated(…) {

    if (viewModel.repository.hasData) {

    viewModel.getData(this)

    }

    }

    fun showData(data: Data) {…}

    }

    class MainViewModel(val repository: Repository) : ViewModel() {

    fun getData(fragment: MainFragment) {

    val data = repository.getData()

    fragment.showData(data)

    }

    }

    View Slide

  71. େࣄͳͷ͸ؔ৺ͷ෼཭
    ιϑτ΢ΣΞ։ൃΛֶͿؔ৺ͷ෼཭
    w .77.΍ϨΠϠʔυ͸໨తͰ͸ͳ͘खஈ
    w lͳͥzͦΕΛ͢Δͷ͔͕େࣄ

    View Slide

  72. ࢹ໺͕޿͕Γࢹ఺͕มΘΔ
    ιϑτ΢ΣΞ։ൃΛֶͿ
    w "OESPJE։ൃͷதͰ΋ଟ͘ͷ͜ͱֶ͕΂Δ
    w ιϑτ΢ΣΞ։ൃͱͯ͠ݟΔ
    w ࣗ෼ͷϓϩμΫτಛ༗ͷ໰୊ʹ޲͖߹͑Δ
    w ΩϟονΞοϓ΁ͷয૩ײ͕ബΕΔ

    View Slide

  73. αʔϏε΁ͷཧղΛਂΊΔ

    View Slide

  74. ͳͥཧղΛਂΊΔඞཁ͕͋Δͷ͔
    w ཧղΛਂΊͯιϑτ΢ΣΞ։ൃʹؐݩ͢Δ
    w αʔϏεͷ஌ࣝΛϞσϧʹ൓өͤ͞Δ
    w ؔ৺ͷ෼཭ʹඞཁͳڥքΛݟ͚ͭΔ
    w ະདྷΛݟਾ͑ͨઃܭ։ൃΛ͢Δ
    w αʔϏεͷํ޲ੑ
    w ։ൃ૊৫ͷະདྷ
    αʔϏε΁ͷཧղΛਂΊΔ

    View Slide

  75. ΤϯδχΞϦϯάͰ
    αʔϏεΛલʹ͢͢ΊΔ

    View Slide

  76. ΤϯδχΞͱͯ͠
    ΩϟϦΞΛ௨ͯ͠ԿΛ͍ͨ͠ʁ

    View Slide

  77. ʰ೥๭೔*5ΤϯδχΞٯٻਓൃදࢿྉ຀ࢁྎʱΑΓ

    View Slide

  78. l։ൃऀͱͯ͠ͷզʑͷ໨ඪ͸ɺʮϢʔβʔΛت͹ͤΔʯ
    ͜ͱͰ͢ɻͦΕ͕ͦ͜զʑͷଘࡏཧ༝ͳͷͰ͢ɻz
    ʰୡਓϓϩάϥϚʔʕख़ୡʹ޲͚ͨ͋ͳͨͷཱྀʕୈ൛ʱQ

    View Slide

  79. ϢʔβʔʹՁ஋Λಧ͚Δ
    w ϓϩͱͯ͠ιϑτ΢ΣΞ։ൃΛ͢Δ
    w ϢʔβʔαʔϏε΁ͷཧղΛਂΊΔ
    w ࣗ෼ͷ੹೚ൣғΛߜΒͳ͍
    ΩϟϦΞΛ௨͍ͯͨ͜͠͠ͱࢲͷ৔߹

    View Slide

  80. lΤϯδχΞϦϯάͱ͍͏ߦҝ͸ɺԿ͔Λʮ࣮ݱʯ͢Δ͜
    ͱͰ͢ɻ࣮ݱͷͨΊʹɺෆ࣮֬ੑͷߴ͍ঢ়ଶ͔Βɺෆ֬
    ࣮ੑͷ௿͍ঢ়ଶʹޮ཰Α͘Ҡ͍ͯ͘͠աఔʹߦ͏͢΂ͯ
    ͷ͜ͱͰ͢ɻz
    ʰΤϯδχΞϦϯά૊৫࿦΁ͷট଴dෆ࣮֬ੑʹ޲͖߹͏ࢥߟͱ૊৫ͷϦϑΝΫλϦϯάʱQ

    View Slide

  81. αʔϏεΛྑ͘Ͱ͖Δ͜ͱɺશ෦΍Δ
    w ΞφϦςΟΫεͷΠϕϯτઃܭ͢Δ
    w ,1*μογϡϘʔυΛ࡞Δ
    w υΩϡϝϯτจԽΛਪਐ͢Δ
    w མ͍ͪͯΔϘʔϧΛੵۃతʹर͏
    w ίϛϡχέʔγϣϯͷػձΛ૿΍͢
    w FUDʜ
    ΩϟϦΞΛ௨͍ͯͨ͜͠͠ͱϢʔβʔʹՁ஋Λಧ͚Δ

    View Slide

  82. ·ͱΊ
    w ࣗ෼ࣗ਎ͷෆ҆ͱ͔ͬ͠Γ޲͖߹͓͏
    w ਓ͔ͩΒͦ͜ςοΫϦʔυͱͯ͠ৼΔ෣͓͏
    w ਓ͔ͩΒͦ͜ΞʔΩςΫτͱͯ͠ৼΔ෣͓͏
    w ΩϟϦΞΛ௨࣮ͯ͠ݱ͍ͨ͜͠ͱͱ޲͖߹͓͏
    w ෆ҆ͱ޲͖߹ָͬͯ͘͠։ൃΛ͠Α͏ʂ

    View Slide