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
Moyuru Aizawa
September 27, 2019
Programming
380
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
290
BluetoothDevice.getName()に裏切られた話
lvla
0
410
Jetpack Composeで画像クロップ機能を実装する
lvla
0
1.3k
Jetpack Compose drag gesture and pinch gesture
lvla
1
4.3k
Jetpack Compose Layout API
lvla
1
710
BLEを使ったアプリを継続的に開発するために
lvla
0
1.1k
RecycledViewPool
lvla
1
290
CameraX
lvla
2
2.5k
Other Decks in Programming
See All in Programming
音楽のための関数型プログラミング言語mimiumにおける多段階計算の活用
tomoyanonymous
1
330
20260623_Loop Engineeringで自分の分身の問い合わせBotを作る
ryugen04
0
220
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
380
ITヒヤリハットを整理してみた ~ライフサイクルと原因から考える再発防止策~
koukimiura
1
110
act2-costs.pdf
sumedhbala
0
110
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
250
ビデオ通話が繋がる0.2秒で何が起きているのか
supurazako
2
150
初めてのKubernetes 本番運用でハマった話
oku053
0
130
エンジニアにデザインハーネスを 〜デザインプロセスを規定するためのハーネス〜 / Design harness from an engineer's perspective
rkaga
2
1.5k
5分で問診!Composer セキュリティ健康診断
codmoninc
0
270
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
0
110
SREは、MCPとSRE Agentをこう使え!
kazumax55
0
150
Featured
See All Featured
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.1k
Building AI with AI
inesmontani
PRO
1
1.1k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
380
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
2
340
The Limits of Empathy - UXLibs8
cassininazir
1
500
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
720
Thoughts on Productivity
jonyablonski
76
5.2k
How STYLIGHT went responsive
nonsquared
100
6.2k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
240
Testing 201, or: Great Expectations
jmmastey
46
8.2k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
270
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