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
スタディサプリ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
450
Sliceのアレコレ
amyu
1
170
ビルド時間を1分短くするためにやったこと
amyu
0
840
ミスを少なくする明日からのCustom Lint Rules
amyu
0
2k
Other Decks in Programming
See All in Programming
わからない話を追いかけたら、プログラミング言語を作る側にいた
ydah
3
560
Go 1.27からのGODEBUG / Go 1.27 リリースパーティ #go127party
mazrean
0
260
[PyCon KR 2026] More Variants, More Diversity for AI Accelerators
achimnol
0
120
Press start. Python's next generation.
willingc
PRO
3
260
リアルな遅延を測る仕様
kota_yata
1
130
TSX の <Hoge<Fuga>> という構文に驚いた話 / tsx-type-argument-syntax
kanaru0928
0
240
「寝てても仕事が進む」Claude Codeで組む第二の脳
tomoyafujita2016
0
370
AI駆動開発にグラフDBを重ねてみた
satoshi256kbyte
1
370
初心者DevRelとして参加者だった私が、DevRel Talks!#2に登壇するまでにしてきたこと
sokohirai
0
160
S3 を使うアプリケーションをローカル完結で動かすことに全力を注いでみた / Running S3 Apps Offline
contour_gara
0
670
バグを直したら useEffect が消えた
colorful12
3
770
freeeにおけるEvalsの実践例の紹介
freee
PRO
0
160
Featured
See All Featured
Music & Morning Musume
bryan
47
7.3k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
650
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
360
How to Think Like a Performance Engineer
csswizardry
28
2.7k
The Invisible Side of Design
smashingmag
301
52k
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.9k
Crafting Experiences
bethany
1
270
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Faster Mobile Websites
deanohume
310
32k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
65
57k
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