[Android] Limit buble text updates at 10Hz
Geoffrey Métais
git at videolan.org
Thu Feb 14 14:15:53 CET 2019
vlc-android | branch: master | Geoffrey Métais <geoffrey.metais at gmail.com> | Thu Feb 14 14:15:12 2019 +0100| [d528cc5d1e4a0a1f12d8d11798376410ead6fc1f] | committer: Geoffrey Métais
Limit buble text updates at 10Hz
> https://code.videolan.org/videolan/vlc-android/commit/d528cc5d1e4a0a1f12d8d11798376410ead6fc1f
---
.../src/org/videolan/vlc/gui/view/FastScroller.kt | 55 ++++++++++------------
.../videolan/vlc/viewmodels/paged/MLPagedModel.kt | 2 +-
.../vlc/viewmodels/paged/PagedAlbumsModel.kt | 3 +-
.../vlc/viewmodels/paged/PagedArtistsModel.kt | 3 +-
.../vlc/viewmodels/paged/PagedTracksModel.kt | 3 +-
5 files changed, 28 insertions(+), 38 deletions(-)
diff --git a/vlc-android/src/org/videolan/vlc/gui/view/FastScroller.kt b/vlc-android/src/org/videolan/vlc/gui/view/FastScroller.kt
index 534f3b4cd..04503f72d 100644
--- a/vlc-android/src/org/videolan/vlc/gui/view/FastScroller.kt
+++ b/vlc-android/src/org/videolan/vlc/gui/view/FastScroller.kt
@@ -44,6 +44,8 @@ import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.floatingactionbutton.FloatingActionButton
import kotlinx.coroutines.*
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.channels.actor
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.vlc.R
import org.videolan.vlc.util.WeakHandler
@@ -61,12 +63,12 @@ private const val SHOW_SCROLLER = 2
private const val ITEM_THRESHOLD = 25
+ at ObsoleteCoroutinesApi
@ExperimentalCoroutinesApi
class FastScroller : LinearLayout, CoroutineScope {
override val coroutineContext = Dispatchers.Main.immediate + SupervisorJob()
private var currentHeight: Int = 0
private var itemCount: Int = 0
- private var recyclerviewTotalHeight: Int = 0
private var fastScrolling: Boolean = false
private var showBubble: Boolean = false
private var currentPosition: Int = 0
@@ -74,6 +76,7 @@ class FastScroller : LinearLayout, CoroutineScope {
private var currentAnimator: AnimatorSet? = null
private val scrollListener = ScrollListener()
private lateinit var recyclerView: RecyclerView
+ private lateinit var layoutManager: LinearLayoutManager
private lateinit var model: MLPagedModel<out MediaLibraryItem>
private lateinit var handle: ImageView
private lateinit var bubble: TextView
@@ -88,9 +91,10 @@ class FastScroller : LinearLayout, CoroutineScope {
private var lastVerticalOffset: Int = 0
private var tryCollapseAppbarOnNextScroll = false
private var tryExpandAppbarOnNextScroll = false
+ private val sb = StringBuilder()
- private val handler = object : FastScrollerHandler(this) {
+ private val handler = object : WeakHandler<FastScroller>(this) {
override fun handleMessage(msg: Message) {
when (msg.what) {
HIDE_HANDLE -> hideBubble()
@@ -155,9 +159,7 @@ class FastScroller : LinearLayout, CoroutineScope {
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
currentHeight = h
- if (::recyclerView.isInitialized) {
- updatePositions()
- }
+ if (::recyclerView.isInitialized) updatePositions()
}
/**
@@ -224,11 +226,11 @@ class FastScroller : LinearLayout, CoroutineScope {
*/
fun setRecyclerView(recyclerView: RecyclerView, model: MLPagedModel<out MediaLibraryItem>) {
this.recyclerView = recyclerView
+ this.layoutManager = recyclerView.layoutManager as LinearLayoutManager
this.recyclerView.removeOnScrollListener(scrollListener)
visibility = View.INVISIBLE
itemCount = recyclerView.adapter!!.itemCount
this.model = model
- recyclerviewTotalHeight = 0
recyclerView.addOnScrollListener(scrollListener)
showBubble = (recyclerView.adapter as SeparatedAdapter).hasSections()
}
@@ -335,39 +337,30 @@ class FastScroller : LinearLayout, CoroutineScope {
tryExpandAppbarOnNextScroll = false
}
}
-
-
}
}
- /**
- * Updates the position of the bubble and refresh the letter
- */
- private fun updatePositions() = launch {
- val sb = StringBuilder()
- val verticalScrollOffset = recyclerView.computeVerticalScrollOffset()
- recyclerviewTotalHeight = recyclerView.computeVerticalScrollRange() - recyclerView.computeVerticalScrollExtent()
- val proportion = if (recyclerviewTotalHeight == 0) 0f else verticalScrollOffset / recyclerviewTotalHeight.toFloat()
- setPosition(currentHeight * proportion)
- if (fastScrolling) {
+ private val actor = actor<Unit>(capacity = Channel.CONFLATED) {
+ for (evt in channel) {
sb.setLength(0)
- val position = if (currentPosition != -1)
- currentPosition
- else
- (recyclerView.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition()
+ val position = layoutManager.findFirstVisibleItemPosition()
val sectionforPosition = model.getSectionforPosition(position)
sb.append(' ')
.append(sectionforPosition)
.append(' ')
- if (!sectionforPosition.isEmpty()) {
- bubble.text = sb.toString()
- }
- return at launch
+ if (!sectionforPosition.isEmpty()) bubble.text = sb.toString()
+ delay(100L)
}
- if (this at FastScroller.visibility == View.INVISIBLE)
- handler.sendEmptyMessage(SHOW_SCROLLER)
}
-
- private open class FastScrollerHandler internal constructor(owner: FastScroller) : WeakHandler<FastScroller>(owner)
-
+ /**
+ * Updates the position of the bubble and refresh the letter
+ */
+ private fun updatePositions() {
+ val verticalScrollOffset = recyclerView.computeVerticalScrollOffset()
+ val recyclerviewTotalHeight = recyclerView.computeVerticalScrollRange() - recyclerView.computeVerticalScrollExtent()
+ val proportion = if (recyclerviewTotalHeight == 0) 0f else verticalScrollOffset / recyclerviewTotalHeight.toFloat()
+ setPosition(currentHeight * proportion)
+ if (visibility == View.INVISIBLE) handler.sendEmptyMessage(SHOW_SCROLLER)
+ if (fastScrolling) actor.offer(Unit)
+ }
}
diff --git a/vlc-android/src/org/videolan/vlc/viewmodels/paged/MLPagedModel.kt b/vlc-android/src/org/videolan/vlc/viewmodels/paged/MLPagedModel.kt
index c4af1e8d8..5a0befe27 100644
--- a/vlc-android/src/org/videolan/vlc/viewmodels/paged/MLPagedModel.kt
+++ b/vlc-android/src/org/videolan/vlc/viewmodels/paged/MLPagedModel.kt
@@ -124,7 +124,7 @@ abstract class MLPagedModel<T : MediaLibraryItem>(context: Context) : SortableMo
}
suspend fun getSectionforPosition(position: Int): String {
- mutex.withLock { for (pos in 0 until headers.size()) if (position < headers.keyAt(pos)) return headers.valueAt(pos) }
+ mutex.withLock { for (pos in 0 until headers.size()) if (position <= headers.keyAt(pos)) return headers.valueAt(pos) }
return ""
}
diff --git a/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedAlbumsModel.kt b/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedAlbumsModel.kt
index 992da7901..b281d1187 100644
--- a/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedAlbumsModel.kt
+++ b/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedAlbumsModel.kt
@@ -45,8 +45,7 @@ class PagedAlbumsModel(context: Context, val parent: MediaLibraryItem? = null) :
is Genre -> parent.searchAlbums(filterQuery, sort, desc, loadSize, startposition)
else -> medialibrary.searchAlbum(filterQuery, sort, desc, loadSize, startposition)
}
- list?.let { completeHeaders(it, startposition) }
- return list
+ return list.also { completeHeaders(it, startposition) }
}
override fun getTotalCount() = if (filterQuery == null) when(parent) {
diff --git a/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedArtistsModel.kt b/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedArtistsModel.kt
index e61666e73..ccfba5fad 100644
--- a/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedArtistsModel.kt
+++ b/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedArtistsModel.kt
@@ -26,8 +26,7 @@ class PagedArtistsModel(context: Context, private var showAll: Boolean = false):
override fun getPage(loadSize: Int, startposition: Int): Array<Artist> {
val list = if (filterQuery == null) medialibrary.getPagedArtists(showAll, sort, desc, loadSize, startposition)
else medialibrary.searchArtist(filterQuery, sort, desc, loadSize, startposition)
- list?.let { completeHeaders(it, startposition) }
- return list
+ return list.also { completeHeaders(it, startposition) }
}
override fun getTotalCount() = if (filterQuery == null) medialibrary.getArtistsCount(showAll)
diff --git a/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedTracksModel.kt b/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedTracksModel.kt
index 27c25018a..c7da221d1 100644
--- a/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedTracksModel.kt
+++ b/vlc-android/src/org/videolan/vlc/viewmodels/paged/PagedTracksModel.kt
@@ -65,8 +65,7 @@ class PagedTracksModel(context: Context, val parent: MediaLibraryItem? = null):
is Playlist -> parent.searchTracks(filterQuery, sort, desc, loadSize, startposition)
else -> medialibrary.searchAudio(filterQuery, sort, desc, loadSize, startposition)
}
- list?.let { completeHeaders(it, startposition) }
- return list
+ return list.also { completeHeaders(it, startposition) }
}
override fun getTotalCount() = if (filterQuery == null) when (parent) {
More information about the Android
mailing list