@@ -46,10 +46,31 @@ class FastScrollerView @JvmOverloads constructor(
4646 defStyleRes
4747) {
4848
49- var iconColor: ColorStateList ? by onUpdate(::bindItemIndicatorViews)
50- var textAppearanceRes: Int by onUpdate(::bindItemIndicatorViews)
51- var textColor: ColorStateList ? by onUpdate(::bindItemIndicatorViews)
52- var textPadding: Float by onUpdate(::bindItemIndicatorViews)
49+ var iconColor: ColorStateList ? = null
50+ set(value) {
51+ field = value
52+ pressedIconColor = value?.getColorForState(intArrayOf(android.R .attr.state_activated))
53+ bindItemIndicatorViews()
54+ }
55+ var textAppearanceRes: Int = 0
56+ set(value) {
57+ field = value
58+ bindItemIndicatorViews()
59+ }
60+ var textColor: ColorStateList ? = null
61+ set(value) {
62+ field = value
63+ pressedTextColor = value?.getColorForState(intArrayOf(android.R .attr.state_activated))
64+ bindItemIndicatorViews()
65+ }
66+ var textPadding: Float = 0f
67+ set(value) {
68+ field = value
69+ bindItemIndicatorViews()
70+ }
71+
72+ private var pressedIconColor: Int? = null
73+ private var pressedTextColor: Int? = null
5374
5475 internal var itemIndicatorsBuilder: ItemIndicatorsBuilder = ItemIndicatorsBuilder ()
5576
@@ -79,7 +100,7 @@ class FastScrollerView @JvmOverloads constructor(
79100 * The function will be called when building the list of indicators, which happens after the
80101 * RecyclerView's adapter's data changes. It will be called on the UI thread.
81102 */
82- var showIndicator: ((FastScrollItemIndicator , Int , Int ) -> Boolean )? by onUpdate {
103+ var showIndicator: ((FastScrollItemIndicator , Int , Int ) -> Boolean )? by onUpdate { _ ->
83104 postUpdateItemIndicators()
84105 }
85106
@@ -235,7 +256,7 @@ class FastScrollerView @JvmOverloads constructor(
235256 }
236257
237258 // Optimize the views by batching adjacent text indicators into a single TextView
238- val viewCreators = ArrayList < () -> View > ()
259+ val views = ArrayList <View >()
239260 itemIndicators.run {
240261 var index = 0
241262 while (index <= lastIndex) {
@@ -244,12 +265,12 @@ class FastScrollerView @JvmOverloads constructor(
244265 .takeWhile { it is FastScrollItemIndicator .Text }
245266 as List <FastScrollItemIndicator .Text >
246267 if (textIndicatorsBatch.isNotEmpty()) {
247- viewCreators .add { createTextView(textIndicatorsBatch) }
268+ views .add( createTextView(textIndicatorsBatch))
248269 index + = textIndicatorsBatch.size
249270 } else {
250271 when (val indicator = this [index]) {
251272 is FastScrollItemIndicator .Icon -> {
252- viewCreators .add { createIconView(indicator) }
273+ views .add( createIconView(indicator))
253274 }
254275 is FastScrollItemIndicator .Text -> {
255276 throw IllegalStateException (" Text indicator wasn't batched" )
@@ -259,19 +280,20 @@ class FastScrollerView @JvmOverloads constructor(
259280 }
260281 }
261282 }
262- viewCreators.forEach { createView ->
263- addView(createView())
264- }
283+ views.forEach(::addView)
265284 }
266285
267286 private fun selectItemIndicator (
268287 indicator : FastScrollItemIndicator ,
269- indicatorCenterY : Int
288+ indicatorCenterY : Int ,
289+ touchedView : View ,
290+ textLine : Int?
270291 ) {
271292 val position = itemIndicatorsWithPositions
272293 .first { it.first == indicator }
273294 .let (ItemIndicatorWithPosition ::second)
274295 if (position != lastSelectedPosition) {
296+ clearSelectedItemIndicator()
275297 lastSelectedPosition = position
276298 if (useDefaultScroller) {
277299 scrollToPosition(position)
@@ -284,12 +306,29 @@ class FastScrollerView @JvmOverloads constructor(
284306 HapticFeedbackConstants .KEYBOARD_TAP
285307 }
286308 )
309+ if (touchedView is ImageView ) {
310+ touchedView.isActivated = true
311+ } else if (textLine != null ) {
312+ pressedTextColor?.let { color ->
313+ TextColorUtil .highlightAtIndex(touchedView as TextView , textLine, color)
314+ }
315+ }
287316 itemIndicatorSelectedCallbacks.forEach {
288317 it.onItemIndicatorSelected(indicator, indicatorCenterY, position)
289318 }
290319 }
291320 }
292321
322+ private fun clearSelectedItemIndicator () {
323+ lastSelectedPosition = null
324+ if (pressedIconColor != null ) {
325+ children.filterIsInstance<ImageView >().forEach { it.isActivated = false }
326+ }
327+ if (pressedTextColor != null ) {
328+ children.filterIsInstance<TextView >().forEach(TextColorUtil ::clearHighlight)
329+ }
330+ }
331+
293332 private fun scrollToPosition (position : Int ) {
294333 recyclerView!! .apply {
295334 stopScroll()
@@ -301,9 +340,9 @@ class FastScrollerView @JvmOverloads constructor(
301340 override fun onTouchEvent (event : MotionEvent ): Boolean {
302341 fun View.containsY (y : Int ) = y in (top until bottom)
303342
304- if (event.action in MOTIONEVENT_STOP_ACTIONS ) {
343+ if (event.actionMasked in MOTIONEVENT_STOP_ACTIONS ) {
305344 isPressed = false
306- lastSelectedPosition = null
345+ clearSelectedItemIndicator()
307346 onItemIndicatorTouched?.invoke(false )
308347 return false
309348 }
@@ -316,7 +355,7 @@ class FastScrollerView @JvmOverloads constructor(
316355 is ImageView -> {
317356 val touchedIndicator = view.tag as FastScrollItemIndicator .Icon
318357 val centerY = view.y.toInt() + (view.height / 2 )
319- selectItemIndicator(touchedIndicator, centerY)
358+ selectItemIndicator(touchedIndicator, centerY, view, textLine = null )
320359 consumed = true
321360 }
322361 is TextView -> {
@@ -332,7 +371,7 @@ class FastScrollerView @JvmOverloads constructor(
332371
333372 val centerY = view.y.toInt() +
334373 (textLineHeight / 2 ) + (touchedIndicatorIndex * textLineHeight)
335- selectItemIndicator(touchedIndicator, centerY)
374+ selectItemIndicator(touchedIndicator, centerY, view, textLine = touchedIndicatorIndex )
336375 consumed = true
337376 }
338377 }
0 commit comments