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
RecyclerView.ItemAnimator
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Moyuru Aizawa
September 27, 2019
Programming
390
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
RecyclerView.ItemAnimator
Moyuru Aizawa
September 27, 2019
More Decks by Moyuru Aizawa
See All by Moyuru Aizawa
BLUETOOTH_SCAN and iBeacon
lvla
1
150
graphicsLayer
lvla
0
300
BluetoothDevice.getName()に裏切られた話
lvla
0
420
Jetpack Composeで画像クロップ機能を実装する
lvla
0
1.3k
Jetpack Compose drag gesture and pinch gesture
lvla
1
4.3k
Jetpack Compose Layout API
lvla
1
720
BLEを使ったアプリを継続的に開発するために
lvla
0
1.1k
RecycledViewPool
lvla
1
300
CameraX
lvla
2
2.6k
Other Decks in Programming
See All in Programming
typoなんかねぇよ
raspython3
0
640
DroidKaigi 2026 「個人開発という実験場: Android エンジニアが手にする4つの自由」
slashnephy
0
180
高専、大学編入、そして未踏へ〜プロダクト開発とキャリアの歩み - Technical College, University Transfer, and On to “Mitou” / My Journey in Product Development and Career
pkmiya
0
130
承認済みなのに差戻しできてしまうバグ、型で潰せます
shinchit
0
130
仕様駆動開発の消費期限
watany
20
9.2k
Go を使い始めて 2 ヶ月の学び / My first two months with Go
contour_gara
0
400
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
5
1.8k
My Marp Sample
sinoue0108
0
140
片田舎のおっさん、 Swift Buildのダイアモンド問題解決の不具合修正PRを出すが、解決方法がキャッシュをしないようにすることであり、ビルド時間が伸びると言われてマージされないので高速化もする/swiftbuild
yimajo
0
340
まずはプロンプトガイドを読もう、話はそれからだ
kiakiraki
1
250
LLMは4年分のCompose移行を再現できるのか?実プロダクト279件のXMLで探る自動化の境界線
makun
0
250
VibeCodingからAgenticWorkflowへ
starfish719
0
1.1k
Featured
See All Featured
Balancing Empowerment & Direction
lara
6
1.3k
Typedesign – Prime Four
hannesfritz
42
3.2k
Technical Leadership for Architectural Decision Making
baasie
3
550
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
910
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.2k
Un-Boring Meetings
codingconduct
0
400
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
400
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
Odyssey Design
rkendrick25
PRO
2
790
Raft: Consensus for Rubyists
vanstee
141
7.7k
Side Projects
sachag
455
43k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
Transcript
RecyclerView.ItemAnimator @MoyuruAizawa
MoyuruAizawa Moyuru Aizawa Software Engineer of Azit Inc. and RABO
Inc. Previously at CyberAgent Inc. and Eureka Inc.
RecyclerViewγϦʔζ☺
‣ RecyclerView.LayoutManager ‣ RecyclerView.ItemDecoration ‣ RecyclerView.RecycledViewPool ‣ RecyclerView.ItemAnimator ‣ https://speakerdeck.com/lvla
RecyclerViewγϦʔζ☺
‣ RecyclerView.Adapterʹมߋ͕ੜͨ࣌͡ͷΞχϝʔγϣϯΛఆٛ͢Δ ‣ Ճ ‣ আ ‣ Ҡಈ ‣ มߋ
‣ Predictive Animations RecyclerView.ItemAnimator
‣ RecyclerView.ItemAnimatorΛܧঝͨ͠நΫϥε ‣ ͍·Θͤͦ͏ͳॲཧΛ༧Ί࣮ͯ͘͠ΕͯΔ ‣ 2ݸؔΛ࣮͢ΕͱΓ͋͑ͣΞχϝʔγϣϯͤ͞ΕΔ SimpleItemAnimator
‣ SimpleItemAnimator#animateXxx [Add | Remove | Move | Change] ‣
SimpleItemAnimator#runPendingAnimations ‣ SimpleItemAnimator#isRunning ‣ SimpleItemAnimator#endAnimation ‣ SimpleItemAnimator#endAnimations SimpleItemAnimator
‣ SimpleItemAnimator#animateXxx [Add | Remove | Move | Change] ‣
SimpleItemAnimator#runPendingAnimations ‣ SimpleItemAnimator#isRunning ‣ SimpleItemAnimator#endAnimation ‣ SimpleItemAnimator#endAnimations SimpleItemAnimator
‣ ࣮ߦ͍ͨ͠ΞχϝʔγϣϯΛఆٛ͢Δؔ ‣ ͜ͷؔͰΞχϝʔγϣϯΛ࣮ߦ͠ͳ͍ ‣ animateAddͰfade in͍ͤͨ͞߹ ‣ ViewͷalphaΛ0ʹ͓ͯ͘͠ ‣
alphaΛ0->1ʹ͢ΔAnimationΛΈཱ͓ͯͯ͘ SimpleItemAnimator#animateXxx
‣ SimpleItemAnimator#animateXxxͰఆٛͨ͠ΞχϝʔγϣϯΛ࣮ߦ͢ Δؔ SimpleItemAnimator#runPendingAnimations
‣ Ξχϝʔγϣϯத͔Ͳ͏͔ฦ͢ SimpleItemAnimator#isRunning
‣ ΞχϝʔγϣϯΛଈ࠲ʹऴ͖ྃ͢ͱ͖ʹݺΕΔ ‣ εΫϩʔϧͳͲͷΠϕϯτ࣌ʹݺΕΔ ‣ Fade inΞχϝʔγϣϯͷ߹ ‣ ΞχϝʔγϣϯΛΩϟϯηϧ͢Δ ‣
alphaΛ1ʹมߋ͢Δ SimpleItemAnimator#endAnimation / endAnimations
class Animator : SimpleItemAnimator() { private val pendingAnimators = LinkedList<ViewPropertyAnimatorCompat>()
private val runningAnimators = LinkedList<ViewPropertyAnimatorCompat>() … override fun animateAdd(holder: RecyclerView.ViewHolder): Boolean { holder.itemView.alpha = 0f ViewCompat.animate(holder.itemView) .alpha(1f) .setDuration(addDuration) .setInterpolator(DecelerateInterpolator()) .let(pendingAnimators::add) return true } } SimpleItemAnimator#animateAdd
class Animator : SimpleItemAnimator() { private val pendingAnimators = LinkedList<ViewPropertyAnimatorCompat>()
private val runningAnimators = LinkedList<ViewPropertyAnimatorCompat>() … override fun animateAdd(holder: RecyclerView.ViewHolder): Boolean { holder.itemView.alpha = 0f ViewCompat.animate(holder.itemView) .alpha(1f) .setDuration(addDuration) .setInterpolator(DecelerateInterpolator()) .let(pendingAnimators::add) return true } } SimpleItemAnimator#animateAdd
class Animator : SimpleItemAnimator() { private val pendingAnimators = LinkedList<ViewPropertyAnimatorCompat>()
private val runningAnimators = LinkedList<ViewPropertyAnimatorCompat>() … override fun animateAdd(holder: RecyclerView.ViewHolder): Boolean { holder.itemView.alpha = 0f ViewCompat.animate(holder.itemView) .alpha(1f) .setDuration(addDuration) .setInterpolator(DecelerateInterpolator()) .let(pendingAnimators::add) return true } } SimpleItemAnimator#animateAdd
class Animator : SimpleItemAnimator() { private val pendingAnimators = LinkedList<ViewPropertyAnimatorCompat>()
private val runningAnimators = LinkedList<ViewPropertyAnimatorCompat>() … override fun animateAdd(holder: RecyclerView.ViewHolder): Boolean { holder.itemView.alpha = 0f ViewCompat.animate(holder.itemView) .alpha(1f) .setDuration(addDuration) .setInterpolator(DecelerateInterpolator()) .let(pendingAnimators::add) return true } } SimpleItemAnimator#animateAdd
class Animator : SimpleItemAnimator() { … override fun runPendingAnimations() {
pendingAnimators.forEach { animation -> animation.setListener(object : ViewPropertyAnimatorListener { override fun onAnimationStart(view: View?) { runningAnimators.add(animation) } override fun onAnimationEnd(view: View?) { runningAnimators.remove(animation) } override fun onAnimationCancel(view: View?) { runningAnimators.remove(animation) } }).start() pendingAnimators.clear() } } } SimpleItemAnimator#pendingAnimations
class Animator : SimpleItemAnimator() { … override fun runPendingAnimations() {
pendingAnimators.forEach { animation -> animation.setListener(object : ViewPropertyAnimatorListener { override fun onAnimationStart(view: View?) { runningAnimators.add(animation) } override fun onAnimationEnd(view: View?) { runningAnimators.remove(animation) } override fun onAnimationCancel(view: View?) { runningAnimators.remove(animation) } }).start() pendingAnimators.clear() } } } SimpleItemAnimator#pendingAnimations
class Animator : SimpleItemAnimator() { … override fun runPendingAnimations() {
pendingAnimators.forEach { animation -> animation.setListener(object : ViewPropertyAnimatorListener { override fun onAnimationStart(view: View?) { runningAnimators.add(animation) } override fun onAnimationEnd(view: View?) { runningAnimators.remove(animation) } override fun onAnimationCancel(view: View?) { runningAnimators.remove(animation) } }).start() pendingAnimators.clear() } } } SimpleItemAnimator#pendingAnimations
class Animator : SimpleItemAnimator() { … override fun runPendingAnimations() {
pendingAnimators.forEach { animation -> animation.setListener(object : ViewPropertyAnimatorListener { override fun onAnimationStart(view: View?) { runningAnimators.add(animation) } override fun onAnimationEnd(view: View?) { runningAnimators.remove(animation) } override fun onAnimationCancel(view: View?) { runningAnimators.remove(animation) } }).start() pendingAnimators.clear() } } } SimpleItemAnimator#pendingAnimations
class Animator : SimpleItemAnimator() { … override fun runPendingAnimations() {
pendingAnimators.forEach { animation -> animation.setListener(object : ViewPropertyAnimatorListener { override fun onAnimationStart(view: View?) { runningAnimators.add(animation) } override fun onAnimationEnd(view: View?) { runningAnimators.remove(animation) } override fun onAnimationCancel(view: View?) { runningAnimators.remove(animation) } }).start() pendingAnimators.clear() } } } SimpleItemAnimator#pendingAnimations
class Animator : SimpleItemAnimator() { private val runningAnimators = LinkedList<ViewPropertyAnimatorCompat>()
override fun isRunning() = runningAnimators.isNotEmpty() override fun endAnimation(item: RecyclerView.ViewHolder) { item.itemView.animation?.cancel() item.itemView.alpha = 1f } … } SimpleItemAnimator#isRunning, endAnimation
Predictive Animations Predictive Animations Predictive Animations
‣ ૿ݮ͢ΔΞΠςϜͷΞχϝʔγϣϯʹ߹ΘͤͯલޙͷΞΠςϜͷҐஔ Λௐ͢Δ ‣ LayoutManager͕Predictive AnimationsʹରԠ͍ͯ͠Δඞཁ͕͋Δ (LinearLayoutManager, GridLayoutManager…) ‣ SimpleItemAnimatorPredictive
Animationsͷ࣮؆୯ ‣ SimpleItemAnimator#animateMoveΛ࣮͢Δ͚ͩ Predictive Animations
class Animator : SimpleItemAnimator() { … override fun animateMove( holder:
RecyclerView.ViewHolder, fromX: Int, fromY: Int, toX: Int, toY: Int ): Boolean { holder.itemView.y = fromY.toFloat() ViewCompat.animate(holder.itemView) .y(toY.toFloat()) .setDuration(moveDuration) .setInterpolator(DecelerateInterpolator()) .let(pendingAnimators::add) return true } } SimpleItemAnimator#animateMove
class Animator : SimpleItemAnimator() { … override fun animateMove( holder:
RecyclerView.ViewHolder, fromX: Int, fromY: Int, toX: Int, toY: Int ): Boolean { holder.itemView.y = fromY.toFloat() ViewCompat.animate(holder.itemView) .y(toY.toFloat()) .setDuration(moveDuration) .setInterpolator(DecelerateInterpolator()) .let(pendingAnimators::add) return true } } SimpleItemAnimator#animateMove
class Animator : SimpleItemAnimator() { … override fun animateMove( holder:
RecyclerView.ViewHolder, fromX: Int, fromY: Int, toX: Int, toY: Int ): Boolean { holder.itemView.y = fromY.toFloat() ViewCompat.animate(holder.itemView) .y(toY.toFloat()) .setDuration(moveDuration) .setInterpolator(DecelerateInterpolator()) .let(pendingAnimators::add) return true } } SimpleItemAnimator#animateMove
Thank You