Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Bonfire Android #6 ৽ Kyash Card Λࢧ͑Δٕज़

Slide 3

Slide 3 text

3 ● 2019/05 ~ Kyash Inc. ● Android applications engineer ● Kyash Point ● Kyash Card ● ࣮ݧతػೳ ● ͳͲ Yoshihiro Tanaka (@_Cordea)

Slide 4

Slide 4 text

4 Kyash Card

Slide 5

Slide 5 text

5 2020೥ॳΊࠒൃߦ༧ఆ

Slide 6

Slide 6 text

6 ● Kyash Card ͷਃ͠ࠐΈ΍ΧʔυઃఆͳͲ ● ৽نͷը໘਺͸ 30 ~ 40 ● Kyash ͷதͰ͸ൺֱతେ͖Ίͷ։ൃن໛ͳͷͰɺઃܭ΍࠾༻ٕज़΋ݟ௚͠ ● ࠓճ͸͜ͷ΁Μͷ࿩Λ͠·͢ ΞϓϦ΋͍Ζ͍Ζ௥Ճ͞Ε·͢

Slide 7

Slide 7 text

7 ● Architecture ͸ MVVM ● Databinding Ͱ VM ͱ View Λ bind ● BaseViewModel ͸ࣗ෼ͨͪͰ࡞ͬͨ΋ͷ ● ࠾༻ٕज़ ● Dagger 2, Retrofit, RxJava ͳͲඪ४తͳબ୒ ● Kyash Point ͷࡍʹ androidx.paging Λ࠾༻͢ΔͳͲ͍ͯ͠Δ ͜Ε·Ͱͷ Kyash Android

Slide 8

Slide 8 text

8 Kyash Card ։ൃʹ͋ͨͬͯߟ͑ͨ͜ͱ

Slide 9

Slide 9 text

9 ● Kyash Android ͷ։ൃ͸ࠓ 1.2 ਓ͘Β͍ ● ࣌ؒͱϦιʔε͕গͳ͍ ● ৽ػೳ΋վળ΋΍Γ͍ͨ͜ͱ͸େྔʹ͋Δ ● ৽͘͠ਓ͕ೖ͖ͬͯͨ࣌ʹ΋ֶशίετ͸௿͘཈͍͑ͨ

Slide 10

Slide 10 text

10 ඪ४ʹد͍ͤͨʂ

Slide 11

Slide 11 text

11 ● ConstraintLayout ● androidx.lifecycle.ViewModel ● Navigation component <- New! ● SpringAnimation <- New! ● Kakao <- New! ࢖༻ٕͨ͠ज़

Slide 12

Slide 12 text

12 ● ͓ೃછΈͷ΍ͭ ● ৽نͷը໘͸΄΅ ConstraintLayout ʹͳ͍ͬͯΔ ● Kyash ͳΒͰ͸ͷԿ͔ͱ͍͏͜ͱͰʮΧʔυ݊໘ͷඳըʯΛ঺հ ConstraintLayout

Slide 13

Slide 13 text

13 Kyash Card Lite ● PAN ͸ Custom view ● Autosizing Ͱ Text size Λௐ੔ ● جຊͷϥΠϯΛ Guideline Ͱఆٛ͠ɺ֤ཁૉͰ percent, chainStyle, bias ͳͲΛઃఆͯ͠૬ޓʹ ઀ଓ͠ܗΛอ͍ͬͯΔ ● ཁ͢ΔʹՄಡੑ͕௿͍

Slide 14

Slide 14 text

14 Kyash Card Lite ● PAN ͸ Custom view ● Autosizing Ͱ Text size Λௐ੔ ● جຊͷϥΠϯΛ Guideline Ͱఆٛ͠ɺ֤ཁૉͰ percent, chainStyle, bias ͳͲΛઃఆͯ͠૬ޓʹ ઀ଓ͠ܗΛอ͍ͬͯΔ ● ཁ͢ΔʹՄಡੑ͕௿͍

Slide 15

Slide 15 text

15 Kyash Card Lite

Slide 16

Slide 16 text

16 Kyash Card ● ͢΂ͯ TextView ● Autosizing Ͱ Text size Λௐ੔ ● ֤ཁૉͷҐஔؔ܎Λ Guideline Ͱఆٛ͠ɺը૾ʹ ର͢Δ percent Ͱࢦఆ͢Δ ● ͞Βʹ weight ͰͦΕͧΕͷ size Λௐ੔͢Δ

Slide 17

Slide 17 text

17 Kyash Card ● ͢΂ͯ TextView ● Autosizing Ͱ Text size Λௐ੔ ● ֤ཁૉͷҐஔؔ܎Λ Guideline Ͱఆٛ͠ɺը૾ʹ ର͢Δ percent Ͱࢦఆ͢Δ ● ͞Βʹ weight ͰͦΕͧΕͷ size Λௐ੔͢Δ

Slide 18

Slide 18 text

18 Kyash Card

Slide 19

Slide 19 text

19 ● Space ΍ ratio ΋ۦ࢖͢Ε͹ෳࡶͳ Layout ΋ ConstraintLayout Ͱ׬݁Ͱ͖Δ ● Preview ͰҰݟͯ͠෼͔Βͳ͍ෳࡶ͞͸อकͰ͖ͳ͍ ConstraintLayout

Slide 20

Slide 20 text

20 ● Kyash Card ͷ৽نը໘Ͱ͸͢΂ͯ androidx.lifecycle.ViewModel ʹ౷Ұ ● Navigation component ͸΋ͱ΋ͱ࠾༻͍ͨ͠ͱ͍͏࿩͕͋ͬͨͷͰ࠾༻ ● ෳ਺ͷը໘ؒͰڞ༗͞ΕΔ Data ΍ Event Ͱ͸ Shared ViewModel Λ࢖༻ ● ਃ͠ࠐΈͷঢ়ଶ؅ཧͷͨΊ ● Nav graph ͕ෳ਺ʹͳ͍ͬͯΔͷͰͦΕຖʹ Shared ViewModel Λ഑ஔ ViewModel & Navigation component

Slide 21

Slide 21 text

21 ● ී௨ʹ࢖༻͢ΔͱඞཁҎ্ͷ Data ʹΞΫηεͰ͖ͯ͠·͏ ● A Fragment ༻ͷ Data ʹ B Fragment ͕ΞΫηεͰ͖ͯ͠·͏ ● ҆શͰ͸ͳ͍ ● ςετͮ͠Β͍ Shared ViewModel ● A Fragment, B Fragment ༻ʹ Interface Λ੾Γɺ͜ΕΛ Inject ͢Δ

Slide 22

Slide 22 text

22 Shared ViewModel ͷ Inject interface CardApplicationSharedViewModel { fun apply() } interface AddressRegistrationSharedViewModel { fun register() } class CardApplicationSharedViewModelImpl( ) : ViewModel(), CardApplicationSharedViewModel, AddressRegistrationSharedViewModel { override fun apply() { } override fun register() { } } @Module class CardApplicationSharedViewModelProvideModule { @Provides fun provideSharedViewModel(activity: AppCompatActivity): CardApplicationSharedViewModel = ViewModelProviders.of(activity).get() } class CardApplicationFragment : Fragment() { @Inject lateinit var sharedViewModel: CardApplicationSharedViewModel }

Slide 23

Slide 23 text

23 ● ϩδοΫΛ Shared ViewModel ʹؚΊΔͱҰؾʹෳࡶԽ͢Δ ● ੹຿Λ͔ͳΓ੍ݶͯ͠ӡ༻͢Δඞཁ͕͋Δ ● ·ͣ͸࢖Θͳͯ͘ྑ͍Α͏ͳํ๏Λߟ͑Δͷ͕͓͢͢Ί Shared ViewModel

Slide 24

Slide 24 text

24 ● View ʹόωͷΑ͏ͳಈ͖Λ༩͑Δɻݮਰൺ΍߶ੑͳͲΛઃఆͰ͖Δɻ ● Kyash Card ͷਃ͠ࠐΈͳͲɺཁॴཁॴʹ༷ʑͳ Animation ͕࢓ࠐ·Ε͍ͯ·͢ ● ΆΑΜΆΑΜ͕͍͔ͭ͋͘Γ͜ΕΛ͍͍ײ͡ʹදݱ͍ͨ͠ͷͰ࠾༻ SpringAnimation

Slide 25

Slide 25 text

25 SpringAnimation fun startAnimation() { scaleX = 1.5f SpringAnimation(this, SpringAnimation.SCALE_X, 1f) .apply { spring.dampingRatio = SpringForce.DAMPING_RATIO_HIGH_BOUNCY spring.stiffness = SpringForce.STIFFNESS_LOW } .start() }

Slide 26

Slide 26 text

26 SpringAnimation

Slide 27

Slide 27 text

27 ● ؆୯ʹɺΑΓࣗવͳಈ͖Λ࣮૷Ͱ͖Δ ● BounceInterpolator ͳͲͷ Interpolator ͱͲͪΒ͕ྑ͍͔ߟ͑ͳ͕Β࢖͏ͷ͕ྑ͍ SpringAnimation

Slide 28

Slide 28 text

28 ● Espresso ͷ DSL ● UI tests Λॻ͖΍ͯ͘͘͢͠ΕΔ ● ςετΛॻ͘͜ͱࣗମʹ࣌ؒΛ͔͚Δͷ͸ຊ࣭తͰ͸ͳ͍ ● ਃ͠ࠐΈͳͲͷҰ࿈ͷྲྀΕΛਓͷखΛ࢖Θͣʹ࣮ߦ͢Δ Kakao

Slide 29

Slide 29 text

29 Espresso object InputPageObject { fun setFirstName() = apply { onView(withId(R.id.first_name_edit_text)).perform(replaceText("Taro")) } fun setLastName() = apply { onView(withId(R.id.last_name_edit_text)).perform(replaceText("Kyash")) } fun clickButton() = apply { onView(withText(getString(R.string.button))).perform(click()) } } class InputTest { @Test fun test() { InputPageObject .setFirstName() .setLastName() .clickButton() } }

Slide 30

Slide 30 text

30 Kakao class InputScreen : Screen() { val firstNameEditText = KEditText { withId(R.id.first_name_edit_text) } val lastNameEditText = KEditText { withId(R.id.last_name_edit_text) } val button = KButton { withText(getString(R.string.button)) } } class InputTest { @Test fun test() { onScreen { firstNameEditText { replaceText("Taro") } lastNameEditText { replaceText("Kyash") } button.click() } } }

Slide 31

Slide 31 text

31 Kakao class ExampleScreen : Screen() { val recyclerView = KRecyclerView({ withId(R.id.recycler_view) }) { itemType(::Item) } class Item(parent: Matcher) : KRecyclerItem(parent) { val title = KTextView(parent) { withId(R.id.title) } val description = KTextView(parent) { withId(R.id.description) } } } class ExampleTest { @Test fun test() { onScreen { recyclerView.children { title { isVisible() hasAnyText() } description { isVisible() isNotClickable() hasEmptyText() } } } } }

Slide 32

Slide 32 text

32 ● UI tests Λॻ࣌ؒ͘͸୹͘ͳΔ ● Espresso ͔Βॻ͖׵͑ͨՕॴͰͨ·ʹࣦഊ͢Δ͜ͱ͕͋Δ ● λΠϛϯά΍ Delay ͸গ͠ௐ੔͢Δඞཁ͕͋ͬͨΓ͢Δ͔΋ Kakao

Slide 33

Slide 33 text

33 ● ConstraintLayout ͸ԿͰ΋ग़དྷΔ ● ΍Γ͗͢ΔͱՄಡੑΛԼ͛Δ ● Shared ViewModel ͷ࢖༻͸৻ॏʹ ● UI tests ʹྗΛೖΕ͍ͯΔ৔߹͸ Kakao ͕ศར ·ͱΊ

Slide 34

Slide 34 text

Thank you 34

Slide 35

Slide 35 text

No content