@@ -58,6 +58,16 @@ class FastScrollerView @JvmOverloads constructor(
5858
5959 private val isSetup: Boolean get() = (recyclerView != null )
6060 private var recyclerView: RecyclerView ? = null
61+ private var adapter: RecyclerView .Adapter <* >? = null
62+ set(value) {
63+ field?.unregisterAdapterDataObserver(adapterDataObserver)
64+ field = value
65+ value?.let { newAdapter ->
66+ newAdapter.registerAdapterDataObserver(adapterDataObserver)
67+ postUpdateItemIndicators()
68+ }
69+ }
70+ private val adapterDataObserver: RecyclerView .AdapterDataObserver = createAdapterDataObserver()
6171 private lateinit var getItemIndicator: (Int ) -> FastScrollItemIndicator ?
6272 /* *
6373 * An optional predicate for deciding which indicators to show after they have been computed.
@@ -161,27 +171,17 @@ class FastScrollerView @JvmOverloads constructor(
161171 this .showIndicator = showIndicator
162172 this .useDefaultScroller = useDefaultScroller
163173
164- updateItemIndicators()
165- val adapter = recyclerView.adapter ? : throw IllegalArgumentException (
166- " RecyclerView needs to have an adapter before setting up its fast scroller."
167- )
168- adapter.registerAdapterDataObserver(object : RecyclerView .AdapterDataObserver () {
169- override fun onChanged () {
170- postUpdateItemIndicators()
174+ this .adapter = recyclerView.adapter.also {
175+ if (it != null ) {
176+ updateItemIndicators()
171177 }
172-
173- override fun onItemRangeChanged (positionStart : Int , itemCount : Int , payload : Any? ) =
174- onChanged()
175-
176- override fun onItemRangeInserted (positionStart : Int , itemCount : Int ) =
177- onChanged()
178-
179- override fun onItemRangeMoved (fromPosition : Int , toPosition : Int , itemCount : Int ) =
180- onChanged()
181-
182- override fun onItemRangeRemoved (positionStart : Int , itemCount : Int ) =
183- onChanged()
184- })
178+ }
179+ recyclerView.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
180+ // RecyclerView#setAdapter calls requestLayout, so this can detect adapter changes
181+ if (recyclerView.adapter != = adapter) {
182+ this @FastScrollerView.adapter = recyclerView.adapter
183+ }
184+ }
185185 }
186186
187187 private fun postUpdateItemIndicators () {
@@ -345,6 +345,29 @@ class FastScrollerView @JvmOverloads constructor(
345345 return consumed
346346 }
347347
348+ companion object {
349+
350+ private fun FastScrollerView.createAdapterDataObserver (): RecyclerView .AdapterDataObserver {
351+ return object : RecyclerView .AdapterDataObserver () {
352+ override fun onChanged () {
353+ postUpdateItemIndicators()
354+ }
355+
356+ override fun onItemRangeChanged (positionStart : Int , itemCount : Int , payload : Any? ) =
357+ onChanged()
358+
359+ override fun onItemRangeInserted (positionStart : Int , itemCount : Int ) =
360+ onChanged()
361+
362+ override fun onItemRangeMoved (fromPosition : Int , toPosition : Int , itemCount : Int ) =
363+ onChanged()
364+
365+ override fun onItemRangeRemoved (positionStart : Int , itemCount : Int ) =
366+ onChanged()
367+ }
368+ }
369+ }
370+
348371 interface ItemIndicatorSelectedCallback {
349372 fun onItemIndicatorSelected (
350373 indicator : FastScrollItemIndicator ,
0 commit comments