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
830
ミスを少なくする明日からのCustom Lint Rules
amyu
0
2k
Other Decks in Programming
See All in Programming
AIで効率化できた業務・日常
ochtum
0
140
技術的負債解消で開発者の未来を開く- AIの力でコード刷新
kmd2kmd
0
110
The ROI of Quarkus for Spring Boot Applications
hollycummins
0
120
気圧・高度・GPSを記録&可視化するアプリ「Koudo」を作った話
hjmkth
1
290
LLM本来の能力を解き放つサンドボックス技術とAI民主化への適用
yukukotani
3
4.3k
Go1.27で導入されるジェネリクスメソッドでできること
mackee
0
140
Dataformのリポジトリを立ち上げるときにまずやること / dataform-day0-2026
snhryt
0
170
Agentic UI
manfredsteyer
PRO
0
180
JJUG CCC 2026 Spring: JSpecify で実現する Kotlin フレンドリーな Java API 設計
ternbusty
1
180
Spring Security 実践 ─ GraphQL APIで実務に役立つ 認証・認可 を学ぶ
wagyu
0
250
Claspは野良GASの夢をみるか
takter00
0
200
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
550
Featured
See All Featured
The Pragmatic Product Professional
lauravandoore
37
7.3k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
480
What does AI have to do with Human Rights?
axbom
PRO
1
2.2k
New Earth Scene 8
popppiees
3
2.3k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
66
55k
Crafting Experiences
bethany
1
180
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
440
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Typedesign – Prime Four
hannesfritz
42
3.1k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4k
Raft: Consensus for Rubyists
vanstee
141
7.5k
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