Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
スタディサプリENGLISHの今と攻めの開発 ~MotionLayout入れてみた~
Search
Yuki Mima
February 05, 2020
Programming
1.9k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
スタディサプリENGLISHの今と攻めの開発 ~MotionLayout入れてみた~
Yuki Mima
February 05, 2020
More Decks by Yuki Mima
See All by Yuki Mima
RecyclerViewで 折れ線グラフを作る
amyu
2
460
Sliceのアレコレ
amyu
1
180
ビルド時間を1分短くするためにやったこと
amyu
0
840
ミスを少なくする明日からのCustom Lint Rules
amyu
0
2k
Other Decks in Programming
See All in Programming
Snowflake Openflow Connector利用の勘所 / 20261024developersio2026tokyo-snowflake-openflow
kasacchiful
PRO
0
270
AIがコードを書いてくれる時代、我々は何を確かめるのか
yosuke_furukawa
PRO
13
5.4k
Getting Started with Vibe Coding
miccheng
0
150
Kotlinize Is Not Just Converting to Kotlin
chigichan24
1
210
AI-Powered Domain-Driven Design
ziobrando
0
370
クラウドゲーミングのパフォーマンス最適化に挑む / Cloud Gaming Performance Tuning
vivion
0
320
JIS keyboard support in Omarchy
lef237
0
180
Python Lambdaにおけるテストしやすい設計とAI支援の活用 / Designing Testable Python Lambda Functions with AI
kitano_yuichi
1
270
當我們開始不讀 Code - AI Agent 時代,Code Review 與 Clean Code 還剩下什麼?
jame2408
1
350
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
220
SODA - FACT BOOK(JP)
sodainc
1
40k
8年前のNode.jsを動かして分かった、npm installの裏側
keisukeikeda
0
120
Featured
See All Featured
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
670
How to make the Groovebox
asonas
2
2.5k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
310
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
740
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
33
5.6k
GitHub's CSS Performance
jonrohan
1033
470k
The Curious Case for Waylosing
cassininazir
1
600
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
2
990
The Cult of Friendly URLs
andyhume
79
7.1k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.8k
Building Adaptive Systems
keathley
44
3.3k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
730
Transcript
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ スタディサプリENGLISHの今と攻めの開発 ~MotionLayout入れてみた~ @amyu Study Sapuri/Quipper Product Meetup #4
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ Agenda | About me スタディサプリENGLISH for Androidの今 MotionLayoutの活用
まとめ 01 02 03 04 2
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ About me 01 3
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ 美馬 優貴 - 2016~社会人 - Android - Github:
amyu - Twitter: @amyu_san 4
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ 5
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ スタディサプリENGLISHの今 02 6
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ スタディサプリENGLISH for Android ➔ 2016年末に開発を開始 ➔ 2017年5月 Kotlin正式サポート
◆ Android Oが発表された ◆ Android Studio 3.0, Architecture Component... ➔ 2017年8月 TOEIC®L&R TEST対策コース をリリース ➔ 2018年5月 ◆ AAB, Jetpack, androidx, AS3.2, Android P, MotionLayout ➔ ... 7
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ スタディサプリENGLISH for Android ➔ Module数: 37 ◆ 機能単位で切られている
◆ ビルドはかなり早い方 ➔ Kotlin率: 75.1% ◆ (Javaは11%) ➔ リリースは当たり前の AAB ➔ Gradle6.0.1, AGP3.5.3, ConstraintLayout, Retrofit, Threetenbp, Dagger, RxJava… ➔ 意味のあるテストコードをしっかり書いてる 8
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ その時点の素晴らしいコードでも 時代とともに負債になってしまう 9
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ MotionLayoutの活用 03 10
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ Before ➔ 横向き、 縦向き対応、 横向き時Transition(Animation)、 縦向き時 Transition(Animation)の4パターンをコードでベタ書きしていた ◆
さらにPdfがあるとき、ないときなど条件が複雑 ➔ UI層(Fragment)で300行くらい関連コードがあった ➔ 全体的に負債が溜まっていたわけではない 12
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ After 縦向き ➔ 開閉TransitionをMotionLayoutへ任せることに より、ロジックから isOpen などの変数を削除でき る
➔ 地味な 矢印 のAnimationもMotionLayoutの Scene xmlへ記述することでスッキリ ◆ 特に clickAction の toggle が便利 13 あとのスライドで実際の Scene xmlを出します
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ After 横向き 14 あとのスライドで実際の Scene xmlを出します ➔ Controllerの出し分けTransitionを
MotionLayoutへ任せることにより、ロジックか ら isVisibleController などの変数を削除でき る ➔ clickAction の toggle が便利
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ After 15 ➔ UI層(Fragment)のTransitionやAnimation, 画面回転の記述が0に ➔ 新規に作ったMovieViewも77行 ➔
関心事が分離できた
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ 実装方法 16 ➔ MotionLayoutのScene XMLを2つ用意 ◆ 縦向き時 ◆
横向き時 ➔ MovieViewはonConfigurationChanged の発火でScene XMLを切り替 えるだけ
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="wrap_content" > <androidx.constraintlayout.motion.widget.MotionLayout app:layoutDescription="@xml/scene_movie_portrait" tools:showPaths="true" > <TextureView android:id="@+id/high_vision_texture_view" /> <jp.eigosapuri.ecp.android.movie.ui.PlaybackControlView android:id="@+id/playback_control_view" /> <ImageView android:id="@+id/open_close_button" /> </androidx.constraintlayout.motion.widget.MotionLayout> </FrameLayout>
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ <?xml version="1.0" encoding="utf-8"?> <MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:motion="http://schemas.android.com/apk/res-auto"> <Transition motion:constraintSetEnd="@+id/scene_movie_end"
motion:constraintSetStart="@+id/scene_movie_start" motion:duration="500"> <OnClick motion:clickAction="toggle" motion:targetId="@+id/open_close_button" /> </Transition> <ConstraintSet android:id="@+id/scene_movie_start"> <Constraint android:id="@+id/high_vision_texture_view"> <Layout motion:layout_constraintTop_toTopOf="parent" /> </Constraint> <Constraint android:id="@+id/open_close_button" android:rotation="0" /> </ConstraintSet> <ConstraintSet android:id="@+id/scene_movie_end"> <Constraint android:id="@+id/high_vision_texture_view"> <Layout motion:layout_constraintBottom_toTopOf="parent" /> </Constraint> <Constraint android:id="@+id/open_close_button" android:rotation="180" /> </ConstraintSet> </MotionScene>
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ <Transition motion:constraintSetEnd="@+id/scene_movie_end" motion:constraintSetStart="@+id/scene_movie_start" motion:duration="500"> <OnClick motion:clickAction="toggle" motion:targetId="@+id/open_close_button" />
</Transition> <ConstraintSet android:id="@+id/scene_movie_start"> </ConstraintSet> <ConstraintSet android:id="@+id/scene_movie_end"> </ConstraintSet>
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ <ConstraintSet android:id="@+id/scene_movie_start"> <Constraint android:id="@+id/high_vision_texture_view"> <Layout motion:layout_constraintTop_toTopOf="parent" /> </Constraint>
</ConstraintSet> <ConstraintSet android:id="@+id/scene_movie_end"> <Constraint android:id="@+id/high_vision_texture_view"> <Layout motion:layout_constraintBottom_toTopOf="parent" /> </Constraint> </ConstraintSet> start end
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ <ConstraintSet android:id="@+id/scene_movie_start"> <Constraint android:id="@+id/open_close_button" android:rotation="0" /> </ConstraintSet> <ConstraintSet
android:id="@+id/scene_movie_end"> <Constraint android:id="@+id/open_close_button" android:rotation="180" /> </ConstraintSet>
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="wrap_content" > <androidx.constraintlayout.motion.widget.MotionLayout app:layoutDescription="@xml/scene_movie_landscape" tools:showPaths="true" > <TextureView android:id="@+id/high_vision_texture_view" /> <jp.eigosapuri.ecp.android.movie.ui.PlaybackControlView android:id="@+id/playback_control_view" /> <ImageView android:id="@+id/open_close_button" /> </androidx.constraintlayout.motion.widget.MotionLayout> </FrameLayout>
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ <?xml version="1.0" encoding="utf-8"?> <MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:motion="http://schemas.android.com/apk/res-auto"> <Transition motion:constraintSetEnd="@+id/scene_movie_landscape_end"
motion:constraintSetStart="@+id/scene_movie_landscape_start" motion:duration="500"> <OnClick motion:clickAction="toggle" motion:targetId="@+id/high_vision_texture_view" /> </Transition> <ConstraintSet android:id="@+id/scene_movie_landscape_start"> <Constraint android:id="@+id/playback_control_view"> <Layout motion:layout_constraintBottom_toBottomOf="parent" /> </Constraint> </ConstraintSet> <ConstraintSet android:id="@+id/scene_movie_landscape_end"> <Constraint android:id="@+id/playback_control_view"> <Layout motion:layout_constraintTop_toBottomOf="parent" /> </Constraint> </ConstraintSet> </MotionScene>
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ <Transition motion:constraintSetEnd="@+id/scene_movie_landscape_end" motion:constraintSetStart="@+id/scene_movie_landscape_start" motion:duration="500"> <OnClick motion:clickAction="toggle" motion:targetId="@+id/high_vision_texture_view" />
</Transition> <ConstraintSet android:id="@+id/scene_movie_landscape_start"> </ConstraintSet> <ConstraintSet android:id="@+id/scene_movie_landscape_end"> </ConstraintSet>
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ <ConstraintSet android:id="@+id/scene_movie_landscape_start"> <Constraint android:id="@+id/playback_control_view"> <Layout motion:layout_constraintBottom_toBottomOf="parent" /> </Constraint>
</ConstraintSet> <ConstraintSet android:id="@+id/scene_movie_landscape_end"> <Constraint android:id="@+id/playback_control_view"> <Layout motion:layout_constraintTop_toBottomOf="parent" /> </Constraint> </ConstraintSet> start end
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ override fun onConfigurationChanged(newConfig: Configuration?) { super.onConfigurationChanged(newConfig) motionLayout.transitionToStart() when
(newConfig?.orientation) { Configuration.ORIENTATION_LANDSCAPE -> { motionLayout.loadLayoutDescription(R.xml.scene_movie_landscape) motionLayout.setTransition(R.id.scene_movie_landscape_start, R.id.scene_movie_landscape_end) } Configuration.ORIENTATION_PORTRAIT -> { motionLayout.loadLayoutDescription(R.xml.scene_movie) motionLayout.setTransition(R.id.scene_movie_start, R.id.scene_movie_end) } } }
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ override fun onConfigurationChanged(newConfig: Configuration?) { super.onConfigurationChanged(newConfig) motionLayout.transitionToStart() when
(newConfig?.orientation) { Configuration.ORIENTATION_LANDSCAPE -> { motionLayout.loadLayoutDescription(R.xml.scene_movie_landscape) motionLayout.setTransition(R.id.scene_movie_landscape_start, R.id.scene_movie_landscape_end) } Configuration.ORIENTATION_PORTRAIT -> { motionLayout.loadLayoutDescription(R.xml.scene_movie) motionLayout.setTransition(R.id.scene_movie_start, R.id.scene_movie_end) } } }
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ まとめ 04 28
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ MotionLayoutについて ➔ まだbeta版だが本番投入しても大丈夫だった ◆ 不具合などは上がってきていない ➔ TransitionやAnimationを直感的に書きなれたXMLでかける ➔
TransitionやAnimationをMotionLayoutにすることで、UI層(Fragmentな ど)がAnimation Helper的な役割から開放される ◆ AnimationやTransitionの状態管理から開放されるだけでもかなりう れしい ◆ clickAction の toggle が便利(3回目) 29
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ 継続的なリファクタリング ➔ 新規案件が始まる前に既存コードの調査、リファクタリングの時間をもらえる ◆ 案件を進める上で障害になりそうなところを先に潰せる ◆ そして将来も開発がしやすいようにしている ➔
日々のキャッチアップをしっかり行う ◆ その時点で最適な技術選択を行えるようにしている 30
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ 弊社、弊チームに来てくれ!!!! 31
#sapurimeetup スタディサプリENGLISHの今と攻めの開発~MotionLayout入れてみた~ ご清聴ありがとうございました 32