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
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
依存関係から依存物へ―Dependencyという言葉の歴史をひも解く
j_lee
0
130
肥大化するレガシーコードに立ち向かうためのインターフェース分離と依存の逆転 / JJUG CCC 2026 Spring
hirokunimaeta
0
610
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
730
AIで効率化できた業務・日常
ochtum
0
140
Webフレームワークの ベンチマークについて
yusukebe
0
180
スマートグラスで並列バイブコーディング
hyshu
0
260
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.3k
技術的負債解消で開発者の未来を開く- AIの力でコード刷新
kmd2kmd
0
110
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
230
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
13
6.2k
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
170
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
0
280
Featured
See All Featured
Leo the Paperboy
mayatellez
7
1.9k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.5k
Ethics towards AI in product and experience design
skipperchong
2
310
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2k
The untapped power of vector embeddings
frankvandijk
2
1.8k
A Modern Web Designer's Workflow
chriscoyier
698
190k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.7k
Building an army of robots
kneath
306
46k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
1
360
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.3k
Testing 201, or: Great Expectations
jmmastey
46
8.2k
My Coaching Mixtape
mlcsv
0
150
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