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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
450
Sliceのアレコレ
amyu
1
180
ビルド時間を1分短くするためにやったこと
amyu
0
840
ミスを少なくする明日からのCustom Lint Rules
amyu
0
2k
Other Decks in Programming
See All in Programming
{ Android | Kotlin } Gradle Plugin in 2026
ryunen344
1
300
LLMは4年分のCompose移行を再現できるのか?実プロダクト279件のXMLで探る自動化の境界線
makun
0
490
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
1k
Hono + Inertia + React で LP を構築した話
oukayuka
2
220
Snowflakeで業務アプリを作ろう。 Snowflakeのアプリ機能解説&実践ガイド
ayumu_yamaguchi
1
210
不幸な GC
chencmd
0
900
kubernetes コンポーネント開発入門 / 新卒N年目の勉強会&交流会!〜〇〇への誘い〜 #n_study
mazrean
0
190
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
250
AI × TiDD / 2026.09.05 Redmine 大阪
tokudiro
1
120
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
190
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
6
1.6k
アクセシビリティから考える情報設計
high_g_engineer
0
350
Featured
See All Featured
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
Darren the Foodie - Storyboard
khoart
PRO
3
3.9k
Code Review Best Practice
trishagee
74
20k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.6k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
The Curse of the Amulet
leimatthew05
2
14k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.6k
The Cost Of JavaScript in 2023
addyosmani
55
10k
Into the Great Unknown - MozCon
thekraken
41
2.7k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
680
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