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

Kyash Androidのイースターエッグ実装 / Kyash Android Easter Eggs

Kyash Androidのイースターエッグ実装 / Kyash Android Easter Eggs

konifar

April 18, 2019
Tweet

More Decks by konifar

Other Decks in Programming

Transcript

  1. Kyash Android ͷ
    ΠʔελʔΤοά࣮૷
    2019/04/18 (໦) Kyash Meetup #6
    Kyash Inc. @konifar

    View Slide

  2. @konifar (Yusuke Konishi)
    • ೖࣾͯ͠1೥4ϲ݄͘Β͍

    http://konifar.hatenablog.com/entry/2019/03/22/222554
    • AndroidΞϓϦ։ൃ͕ϝΠϯ
    • ೖ͙ࣾͯ͢͠ʹ39ΞχϝʔγϣϯΛ࣮૷

    View Slide

  3. View Slide

  4. ΠʔελʔΤοά
    = ָ͓͠Έػೳ

    View Slide

  5. ࡩΞχϝʔγϣϯ
    • ࡩͬΆ͍จࣈΛτϦΨʔ

    ʹͯ͠ɺࡩ͕෣͍ࢄΔʂ

    View Slide

  6. http://konifar.hatenablog.com/entry/2018/06/14/173716
    ࡩΞχϝʔγϣϯͷ͖͔͚ͬ

    View Slide

  7. ࢭ·Βͳ͍ཉ๬

    View Slide

  8. ࠓ͸ͨͿΜ
    7छྨ͘Β͍͋Δ

    View Slide

  9. ΠʔελʔΤοάͷ
    ίʔυ෦෼ͷ࿩Λ͠·͢

    View Slide

  10. ੲͱࠓͷίʔυͷ࿩

    View Slide

  11. 39Ξχϝʔγϣϯ͚ͩͷࠒ
    • ཤྺৄࡉը໘ͷViewModelͷҰ෦ʹ͸ͼ͜Δ is39() ϝιου
    • ౰࣌͸͜Μͳʹָ͠ΜͰ΋Β֦͑ͯு͍ͯ͘͠ͱ͸ࢥͬͯͳ͔ͬͨ

    View Slide

  12. ந৅Խ͢Δ

    View Slide

  13. ΠʔελʔΤοάͷ෼ղ
    1. ର৅ͷ৔ॴʹ
    2. ৚݅ʹԠͯ͡
    3. Կ͔Λදࣔ͢Δ

    View Slide

  14. 39Ξχϝʔγϣϯͷ৔߹
    1. ର৅ͷ৔ॴʹʢૹۚ׬ྃը໘શମʹʣ
    2. ৚݅ʹԠͯ͡ʢ39ԁͩͬͨ৔߹ʹʣ
    3. Կ͔Λදࣔ͢ΔʢgifΛදࣔ͢Δʣ

    View Slide

  15. ࡩΞχϝʔγϣϯͷ৔߹
    1. ର৅ͷ৔ॴʹʢཤྺৄࡉը໘શମʹʣ
    2. ৚݅ʹԠͯ͡ʢ࠷ޙͷϝοηʔδʹࡩͬΆ͍จࣈ͕ೖ͍ͬͯͨ৔߹ʹʣ
    3. Կ͔Λදࣔ͢ΔʢՖͼΒͷը૾Λ߱ΒͤΔʣ

    View Slide

  16. ࠓͷΞϯυϩΠυͷ࣮૷
    7JFX.PEFM
    5JNFMJOF)FBEFS
    &BTUFS&HH'BDUPSZ
    &BTUFS&HH,FZXPSE

    .BUDIFS
    5JNFMJOF)FBEFS
    &BTUFS&HH
    5JNFMJOF)FBEFS
    &BTUFS&HH
    5JNFMJOF)FBEFS
    &BTUFS&HH
    EasterEggΛදࣔ͢ΔViewModel͔Β
    Factoryܦ༝ͰEasterEggΦϒδΣΫτΛऔ
    Γग़͢
    EasterEggΠϯλʔϑΣʔεΛ࣮૷ͯ͠
    ʰදࣔ৚݅ʱͱʰදࣔ͢ΔϦιʔεʱΛࢦ
    ఆ͢Δ
    දࣔ৚݅͸ɺଞͷը໘ͷEasterEggΫϥε
    ͱڞ௨ͳͷͰɺMatcherΫϥεͱͯ͠੾Γ
    ग़͍ͯ͠Δ

    View Slide

  17. |--keywords
    | |--EasterEggKeywordsMatcher.kt
    | |-—SakuraEasterEggKeywordsMatcher.kt
    | |……
    |--timeline
    | |--NoTimelineHeaderEasterEgg.kt
    | |--ThankYouReceiveTimelineHeaderEasterEgg.kt
    | |--TimelineHeaderEasterEgg.kt
    | |-—TimelineHeaderEasterEggFactory.kt
    | |……
    |--transaction
    | |--NoTransactionEasterEgg.kt
    | |--ThankYouSendTransactionEasterEgg.kt
    | |--TransactionEasterEgg.kt
    | |--TransactionEasterEggFactory.kt
    | |……
    • UI૚ͷσΟϨΫτϦͷதʹeastereggsσΟϨΫτϦΛஔ͍͍ͯΔ

    View Slide

  18. |--keywords
    | |--EasterEggKeywordsMatcher.kt
    | |-—SakuraEasterEggKeywordsMatcher.kt
    | |……
    |--timeline
    | |--NoTimelineHeaderEasterEgg.kt
    | |--ThankYouReceiveTimelineHeaderEasterEgg.kt
    | |--TimelineHeaderEasterEgg.kt
    | |-—TimelineHeaderEasterEggFactory.kt
    | |……
    |--transaction
    | |--NoTransactionEasterEgg.kt
    | |--ThankYouSendTransactionEasterEgg.kt
    | |--TransactionEasterEgg.kt
    | |--TransactionEasterEggFactory.kt
    | |……
    • ʮର৅ͷ৔ॴʯ͝ͱʹEasterEggΫϥεͱFactoryΫϥεΛ࡞͍ͬͯΔ
    • timeline = ཤྺৄࡉը໘্෦
    • transaction = ૹۚɾ੥ٻ׬ྃը໘શମ

    View Slide

  19. interface TimelineHeaderEasterEgg {
    @DrawableRes
    fun getAnimationDrawableResId(): Int?
    fun shouldShow(): Boolean
    }
    • λΠϜϥΠϯৄࡉͷ39ΞχϝʔγϣϯͷΠϯλʔϑΣʔε
    • Կ΋දࣔ͠ͳ͍έʔεͷͨΊʹɺNullObjectύλʔϯͷΑ͏ͳܗͰ
    NoTransactionEasterEggΫϥε΋࡞͍ͬͯΔ
    class NoTransactionEasterEgg : TransactionEasterEgg {
    override fun getAnimationDrawableResId(): Int? = null
    override fun shouldShow() = false
    }

    View Slide

  20. /**
    * डऔ࣌ͷ39Ξχϝʔγϣϯ
    */
    class ThankYouReceiveTimelineHeaderEasterEgg(
    val amount: Long
    ) : TimelineHeaderEasterEgg {
    override fun getAnimationDrawableResId() =
    R.drawable.img_receive_39
    override fun shouldShow() = amount == 39L
    }
    • 39ԁΛड͚औͬͨ৔߹ͷ࣮૷
    • දࣔ৚݅ͱͳΔ shouldShow() ͷςετΛ͔ͬ͠Γॻ͍͍ͯΔ

    View Slide

  21. class SakuraEasterEggKeywordsMatcher : EasterEggKeywordsMatcher {
    override fun getKeywords() = arrayListOf(
    "͘͞Β",
    "αΫϥ",
    "ࡩ",
    "Ֆݟ",
    "͸ͳΈ",
    "ϋφϛ",
    "ԅ",
    String(byteArrayOf(-16, -97, -116, -72)) // ࡩͷemoji
    )
    }
    • ͘͞ΒΞχϝʔγϣϯͷΩʔϫʔυΛఆٛ
    • JUnitͰParameterized TestΛॻ͘

    View Slide

  22. @RunWith(Parameterized::class)
    class SakuraEasterEggKeywordsMatcherUnitTest(
    private val message: String,
    private val result: Boolean
    ) {
    companion object {
    @JvmStatic
    @Parameterized.Parameters
    fun data(): List> {
    return listOf(
    arrayOf("αΫϥ͕͘͞", true),

    arrayOf("", true),
    arrayOf("α Ϋϥ", false),

    ……
    )
    }
    }
    @Test
    fun containsKeyword() {

    val subject = SakuraEasterEggKeywordsMatcher()
    assertEquals(result, subject.containsKeyword(message))
    }
    }

    View Slide

  23. class TimelineHeaderEasterEggFactory(
    val amount: Long,
    val message: String?
    ) {
    // ద༻͞ΕΔॱʹϦετʹηοτ͍ͯ͠·͢
    private val easterEggs = arrayListOf(
    … // ωλόϨʹͳΔͷͰφΠγϣ
    ThankYouReceiveTimelineHeaderEasterEgg(amount)
    )
    fun createEasterEgg(): TimelineHeaderEasterEgg {
    easterEggs.forEach {
    if (it.shouldShow()) return it
    }
    return NoTimelineHeaderEasterEgg()
    }
    }
    • Factory͸ɺEasterEggͷϦετΛ࣋ͬͯɺ৚݅ʹԠͯ͡࠷ॳʹද
    ࣔ৚݅ʹ߹கͨ͠EasterEggΛฦ͢

    View Slide

  24. val easterEgg = TimelineHeaderEasterEggFactory(

    amount, 

    message

    ).createEasterEgg()

    …

    @get:Bindable
    val headerEasterEggVisible: Boolean
    get() = easterEgg.shouldShow()
    @get:Bindable
    val headerEasterEggDrawable: Int?
    get() = easterEgg.getAnimationDrawableResId()
    • ViewModelͰEasterEggΛݩʹDataBindingͷ஋ΛܾΊͯBind
    • AnimationDrawableResId͸gifͳͷͰɺGifDrawableΛbindͰ͖
    ΔBindingAdapterΛ࡞͍ͬͯΔ

    https://github.com/koral--/android-gif-drawable

    View Slide

  25. ࠓޙͷίʔυͷ࿩

    View Slide

  26. ʮͦ΋ͦ΋αʔόʔαΠ
    υʹϩδοΫ͋Δ΂͖
    ͡Όͳ͍ʁʯ

    View Slide

  27. ʮͦ͏ͩͶʂʂʯ

    View Slide

  28. ࠓޙͷ໺๬
    • Android/iOSʹϩδοΫ͕ࢄΒ͹Βͳ͍Α͏ʹαʔ
    όʔαΠυʹϩδοΫΛدͤΔ = APIԽ
    • ΞχϝʔγϣϯϑΝΠϧΛΫϥΠΞϯτଆͰ࣋ͨͳ
    ͍Α͏ʹμ΢ϯϩʔυͷ࢓૊ΈΛ༻ҙ͢Δ = Ξϓ
    ϦαΠζͷ࡟ݮ
    • ΫϥΠΞϯτͰͷந৅ԽͰ࢓༷͕ݻ·͖ͬͯͨࠓͳ
    Β΍͍͚ͬͯͦ͏

    View Slide

  29. View Slide

  30. ͍Ζ͍Ζࢼͯ͠܅͚ͩͷ
    ΠʔελʔΤοάΛ୳ͦ͏ʂ
    ※ ͪͳΈʹࣗ෼ͷkyash_id͸ konifar ͩΑ

    View Slide

  31. ࠙਌ձͰฉ͍ͯ΋Β͑Ε͹
    Ͱ͖Δ͚ͩԿͰ΋࿩͠·͢
    ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ

    View Slide