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

35e08efcf39d692f540047fb756eb4e3?s=47 konifar
April 18, 2019

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

35e08efcf39d692f540047fb756eb4e3?s=128

konifar

April 18, 2019
Tweet

Transcript

  1. 3.
  2. 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Ϋϥεͱͯ͠੾Γ ग़͍ͯ͠Δ
  3. 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σΟϨΫτϦΛஔ͍͍ͯΔ
  4. 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 = ૹۚɾ੥ٻ׬ྃը໘શମ
  5. 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 }
  6. 20.

    /** * डऔ࣌ͷ39Ξχϝʔγϣϯ */ class ThankYouReceiveTimelineHeaderEasterEgg( val amount: Long )

    : TimelineHeaderEasterEgg { override fun getAnimationDrawableResId() = R.drawable.img_receive_39 override fun shouldShow() = amount == 39L } • 39ԁΛड͚औͬͨ৔߹ͷ࣮૷ • දࣔ৚݅ͱͳΔ shouldShow() ͷςετΛ͔ͬ͠Γॻ͍͍ͯΔ
  7. 21.

    class SakuraEasterEggKeywordsMatcher : EasterEggKeywordsMatcher { override fun getKeywords() = arrayListOf(

    "͘͞Β", "αΫϥ", "ࡩ", "Ֆݟ", "͸ͳΈ", "ϋφϛ", "ԅ", String(byteArrayOf(-16, -97, -116, -72)) // ࡩͷemoji ) } • ͘͞ΒΞχϝʔγϣϯͷΩʔϫʔυΛఆٛ • JUnitͰParameterized TestΛॻ͘
  8. 22.

    @RunWith(Parameterized::class) class SakuraEasterEggKeywordsMatcherUnitTest( private val message: String, private val result:

    Boolean ) { companion object { @JvmStatic @Parameterized.Parameters fun data(): List<Array<out Any?>> { return listOf( arrayOf("αΫϥ͕͘͞", true),
 arrayOf("", true), arrayOf("α Ϋϥ", false),
 …… ) } } @Test fun containsKeyword() {
 val subject = SakuraEasterEggKeywordsMatcher() assertEquals(result, subject.containsKeyword(message)) } }
  9. 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Λฦ͢
  10. 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
  11. 29.