Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
新 Kyash Card を支える技術
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Yoshihiro Tanaka
January 16, 2020
Technology
3.3k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
新 Kyash Card を支える技術
Bonfire Android #6 での発表資料です
https://yj-meetup.connpass.com/event/158328/
Yoshihiro Tanaka
January 16, 2020
More Decks by Yoshihiro Tanaka
See All by Yoshihiro Tanaka
Nim and sha1
cordea
0
530
Possibility of terminal
cordea
0
1.6k
Other Decks in Technology
See All in Technology
DEFCON34-Write-up_HYCu-MYCu
daikiokazaki
0
110
Benchmarking Vector Databases: pgvector vs. LanceDB
tsho
0
150
AIとペアプロを始める。人とのペアプロをやめる。ペアプロの良さを改めて知る。もっと好きになった。 / Rediscovering Pair Programming
honyanya
1
290
Adaptive Warehouse を今すぐ導入すべき理由と迷ったときの判断基準
__allllllllez__
0
120
Snowflakeで実現する全社横断の顧客の声(VOC)分析・活用基盤@Snowflake World Tour Tokyo 2026
yuto16
0
120
Sigmaユーザーのための有用リソース一挙公開 & Sigmaで使えるMCP #sigma_ucj /useful-resources-for-sigma-computing-users-and-mcps-with-sigma
shinyaa31
0
170
SQL文一行も書けない人事がCortexもろもろを使って人事業務を楽にしてみる
ponponmikankan
1
150
2026/09/10 Spring_Bootから_Jakarta_EE_MicroProfileへの移行
megascus
0
240
Screen Lens - 今見てる画面を翻訳する
komagata
0
130
ペアプロの価値はコードを書くことだけじゃない
codmoninc
PRO
0
140
Amazon Quick on DesktopがIAM Identity Centerで動かない理由
yukiogawa
0
110
10分で知る最近のOmarchy
komagata
0
140
Featured
See All Featured
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
190
New Earth Scene 8
popppiees
3
2.5k
Building Adaptive Systems
keathley
44
3.2k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
520
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
2
3.8k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
430
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
230
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
660
Six Lessons from altMBA
skipperchong
29
4.5k
Writing Fast Ruby
sferik
630
63k
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
Transcript
None
Bonfire Android #6 ৽ Kyash Card Λࢧ͑Δٕज़
3 • 2019/05 ~ Kyash Inc. • Android applications engineer
• Kyash Point • Kyash Card • ࣮ݧతػೳ • ͳͲ Yoshihiro Tanaka (@_Cordea)
4 Kyash Card
5 2020ॳΊࠒൃߦ༧ఆ
6 • Kyash Card ͷਃ͠ࠐΈΧʔυઃఆͳͲ • ৽نͷը໘ 30 ~ 40
• Kyash ͷதͰൺֱతେ͖Ίͷ։ൃنͳͷͰɺઃܭ࠾༻ٕज़ݟ͠ • ࠓճ͜ͷΜͷΛ͠·͢ ΞϓϦ͍Ζ͍ΖՃ͞Ε·͢
7 • Architecture MVVM • Databinding Ͱ VM ͱ
View Λ bind • BaseViewModel ࣗͨͪͰ࡞ͬͨͷ • ࠾༻ٕज़ • Dagger 2, Retrofit, RxJava ͳͲඪ४తͳબ • Kyash Point ͷࡍʹ androidx.paging Λ࠾༻͢ΔͳͲ͍ͯ͠Δ ͜Ε·Ͱͷ Kyash Android
8 Kyash Card ։ൃʹ͋ͨͬͯߟ͑ͨ͜ͱ
9 • Kyash Android ͷ։ൃࠓ 1.2 ਓ͘Β͍ • ࣌ؒͱϦιʔε͕গͳ͍ •
৽ػೳվળΓ͍ͨ͜ͱେྔʹ͋Δ • ৽͘͠ਓ͕ೖ͖ͬͯͨ࣌ʹֶशίετ͍͑ͨ͘
10 ඪ४ʹد͍ͤͨʂ
11 • ConstraintLayout • androidx.lifecycle.ViewModel • Navigation component <- New!
• SpringAnimation <- New! • Kakao <- New! ༻ٕͨ͠ज़
12 • ͓ೃછΈͷͭ • ৽نͷը໘΄΅ ConstraintLayout ʹͳ͍ͬͯΔ • Kyash ͳΒͰͷԿ͔ͱ͍͏͜ͱͰʮΧʔυ݊໘ͷඳըʯΛհ
ConstraintLayout
13 Kyash Card Lite • PAN Custom view •
Autosizing Ͱ Text size Λௐ • جຊͷϥΠϯΛ Guideline Ͱఆٛ͠ɺ֤ཁૉͰ percent, chainStyle, bias ͳͲΛઃఆͯ͠૬ޓʹ ଓ͠ܗΛอ͍ͬͯΔ • ཁ͢ΔʹՄಡੑ͕͍
14 Kyash Card Lite • PAN Custom view •
Autosizing Ͱ Text size Λௐ • جຊͷϥΠϯΛ Guideline Ͱఆٛ͠ɺ֤ཁૉͰ percent, chainStyle, bias ͳͲΛઃఆͯ͠૬ޓʹ ଓ͠ܗΛอ͍ͬͯΔ • ཁ͢ΔʹՄಡੑ͕͍
15 Kyash Card Lite <TextView android:id="@+id/exp_label" app:autoSizeMinTextSize="5sp" app:autoSizeTextType="uniform" app:layout_constraintBottom_toTopOf="@id/exp" app:layout_constraintEnd_toEndOf="@id/exp"
app:layout_constraintHeight_percent="0.05" app:layout_constraintStart_toStartOf="@id/exp" app:layout_constraintTop_toBottomOf="@id/guideline" /> <TextView android:id="@+id/exp" android:layout_marginStart="16dp" app:autoSizeMinTextSize="12sp" app:autoSizeTextType="uniform" app:layout_constraintEnd_toStartOf="@id/cvv" app:layout_constraintHeight_percent="0.08" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/exp_label" app:layout_constraintWidth_percent="0.2" />
16 Kyash Card • ͯ͢ TextView • Autosizing Ͱ Text
size Λௐ • ֤ཁૉͷҐஔؔΛ Guideline Ͱఆٛ͠ɺը૾ʹ ର͢Δ percent Ͱࢦఆ͢Δ • ͞Βʹ weight ͰͦΕͧΕͷ size Λௐ͢Δ
17 Kyash Card • ͯ͢ TextView • Autosizing Ͱ Text
size Λௐ • ֤ཁૉͷҐஔؔΛ Guideline Ͱఆٛ͠ɺը૾ʹ ର͢Δ percent Ͱࢦఆ͢Δ • ͞Βʹ weight ͰͦΕͧΕͷ size Λௐ͢Δ
18 Kyash Card <TextView android:id="@+id/exp" app:autoSizeMinTextSize="5sp" app:autoSizeTextType="uniform" app:layout_constraintBottom_toTopOf="@id/bottom_guideline" app:layout_constraintEnd_toStartOf="@id/end_guideline" app:layout_constraintHorizontal_weight="2"
app:layout_constraintStart_toEndOf="@id/good_thru" app:layout_constraintTop_toBottomOf="@id/month_year" app:layout_constraintVertical_weight="2" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/top_guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.1" />
19 • Space ratio ۦ͢Εෳࡶͳ Layout ConstraintLayout Ͱ݁Ͱ͖Δ
• Preview ͰҰݟ͔ͯ͠Βͳ͍ෳࡶ͞อकͰ͖ͳ͍ ConstraintLayout
20 • Kyash Card ͷ৽نը໘Ͱͯ͢ androidx.lifecycle.ViewModel ʹ౷Ұ • Navigation component
ͱͱ࠾༻͍ͨ͠ͱ͍͏͕͋ͬͨͷͰ࠾༻ • ෳͷը໘ؒͰڞ༗͞ΕΔ Data Event Ͱ Shared ViewModel Λ༻ • ਃ͠ࠐΈͷঢ়ଶཧͷͨΊ • Nav graph ͕ෳʹͳ͍ͬͯΔͷͰͦΕຖʹ Shared ViewModel Λஔ ViewModel & Navigation component
21 • ී௨ʹ༻͢ΔͱඞཁҎ্ͷ Data ʹΞΫηεͰ͖ͯ͠·͏ • A Fragment ༻ͷ Data
ʹ B Fragment ͕ΞΫηεͰ͖ͯ͠·͏ • ҆શͰͳ͍ • ςετͮ͠Β͍ Shared ViewModel • A Fragment, B Fragment ༻ʹ Interface ΛΓɺ͜ΕΛ Inject ͢Δ
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<CardApplicationSharedViewModelImpl>() } class CardApplicationFragment : Fragment() { @Inject lateinit var sharedViewModel: CardApplicationSharedViewModel }
23 • ϩδοΫΛ Shared ViewModel ʹؚΊΔͱҰؾʹෳࡶԽ͢Δ • Λ͔ͳΓ੍ݶͯ͠ӡ༻͢Δඞཁ͕͋Δ • ·ͣΘͳͯ͘ྑ͍Α͏ͳํ๏Λߟ͑Δͷ͕͓͢͢Ί
Shared ViewModel
24 • View ʹόωͷΑ͏ͳಈ͖Λ༩͑Δɻݮਰൺ߶ੑͳͲΛઃఆͰ͖Δɻ • Kyash Card ͷਃ͠ࠐΈͳͲɺཁॴཁॴʹ༷ʑͳ Animation ͕ࠐ·Ε͍ͯ·͢
• ΆΑΜΆΑΜ͕͍͔ͭ͋͘Γ͜ΕΛ͍͍ײ͡ʹදݱ͍ͨ͠ͷͰ࠾༻ SpringAnimation
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() }
26 SpringAnimation
27 • ؆୯ʹɺΑΓࣗવͳಈ͖Λ࣮Ͱ͖Δ • BounceInterpolator ͳͲͷ Interpolator ͱͲͪΒ͕ྑ͍͔ߟ͑ͳ͕Β͏ͷ͕ྑ͍ SpringAnimation
28 • Espresso ͷ DSL • UI tests Λॻ͖ͯ͘͘͢͠ΕΔ •
ςετΛॻ͘͜ͱࣗମʹ࣌ؒΛ͔͚Δͷຊ࣭తͰͳ͍ • ਃ͠ࠐΈͳͲͷҰ࿈ͷྲྀΕΛਓͷखΛΘͣʹ࣮ߦ͢Δ Kakao
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() } }
30 Kakao class InputScreen : Screen<InputScreen>() { 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<InputScreen> { firstNameEditText { replaceText("Taro") } lastNameEditText { replaceText("Kyash") } button.click() } } }
31 Kakao class ExampleScreen : Screen<ExampleScreen>() { val recyclerView =
KRecyclerView({ withId(R.id.recycler_view) }) { itemType(::Item) } class Item(parent: Matcher<View>) : KRecyclerItem<Item>(parent) { val title = KTextView(parent) { withId(R.id.title) } val description = KTextView(parent) { withId(R.id.description) } } } class ExampleTest { @Test fun test() { onScreen<ExampleScreen> { recyclerView.children<ExampleScreen.Item> { title { isVisible() hasAnyText() } description { isVisible() isNotClickable() hasEmptyText() } } } } }
32 • UI tests Λॻ࣌ؒ͘͘ͳΔ • Espresso ͔Βॻ͖͑ͨՕॴͰͨ·ʹࣦഊ͢Δ͜ͱ͕͋Δ • λΠϛϯά
Delay গ͠ௐ͢Δඞཁ͕͋ͬͨΓ͢Δ͔ Kakao
33 • ConstraintLayout ԿͰग़དྷΔ • Γ͗͢ΔͱՄಡੑΛԼ͛Δ • Shared ViewModel ͷ༻৻ॏʹ
• UI tests ʹྗΛೖΕ͍ͯΔ߹ Kakao ͕ศར ·ͱΊ
Thank you 34
None