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
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
410
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
[PyCon KR 2026] More Variants, More Diversity for AI Accelerators
achimnol
0
120
AI駆動開発にグラフDBを重ねてみた
satoshi256kbyte
1
370
実装をデザインガイドラインに追従させるための取り組み / 260731-dip-mosh-design-system
dachi023
0
7.9k
AI Readyの正体はデータマネジメントだ メダリオン2.0の最前線
freee
PRO
0
420
ALB ログから Trace を気合で繋げる技術
fohte
7
770
T3DD26: From RAGs to Riches
martinhelmich
0
110
S3 を使うアプリケーションをローカル完結で動かすことに全力を注いでみた / Running S3 Apps Offline
contour_gara
0
670
バグを直したら useEffect が消えた
colorful12
3
770
VibeCodingからAgenticWorkflowへ
starfish719
0
940
使いながら育てる Claude Code — 開発フローの1コマンド化 × 繰り返し指摘の自動仕組み化
shiki_kakaku
1
2k
Flow は今どうなっているか
mizdra
PRO
0
760
不幸な GC
chencmd
0
810
Featured
See All Featured
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
220
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
510
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
6
1.2k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
Bash Introduction
62gerente
615
220k
Building Applications with DynamoDB
mza
96
7.2k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
360
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
420
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
480
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