[Android] Fix empty view not displayed after deleting last Video
Nicolas Pomepuy
git at videolan.org
Thu Jul 2 11:51:03 CEST 2020
vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Thu Jul 2 09:31:01 2020 +0200| [5b021f2afcd165294ac46955e42c199dff6d4e20] | committer: Nicolas Pomepuy
Fix empty view not displayed after deleting last Video
Fixes #1382
> https://code.videolan.org/videolan/vlc-android/commit/5b021f2afcd165294ac46955e42c199dff6d4e20
---
.../videolan/vlc/gui/video/VideoGridFragment.kt | 4 ++
.../src/org/videolan/vlc/util/Kextensions.kt | 46 ++++++++++++++++++++++
2 files changed, 50 insertions(+)
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.kt b/application/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.kt
index 870356d8d..b4ad9f72e 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.kt
@@ -60,6 +60,7 @@ import org.videolan.vlc.media.getAll
import org.videolan.vlc.providers.medialibrary.VideosProvider
import org.videolan.vlc.reloadLibrary
import org.videolan.vlc.util.launchWhenStarted
+import org.videolan.vlc.util.onAnyChange
import org.videolan.vlc.util.share
import org.videolan.vlc.viewmodels.mobile.VideoGroupingType
import org.videolan.vlc.viewmodels.mobile.VideosViewModel
@@ -72,6 +73,7 @@ private const val TAG = "VLC/VideoListFragment"
@ExperimentalCoroutinesApi
class VideoGridFragment : MediaBrowserFragment<VideosViewModel>(), SwipeRefreshLayout.OnRefreshListener, CtxActionReceiver {
+ private lateinit var dataObserver: RecyclerView.AdapterDataObserver
private lateinit var videoListAdapter: VideoListAdapter
private lateinit var multiSelectHelper: MultiSelectHelper<MediaLibraryItem>
private lateinit var binding: VideoGridBinding
@@ -92,6 +94,7 @@ class VideoGridFragment : MediaBrowserFragment<VideosViewModel>(), SwipeRefreshL
if (!::videoListAdapter.isInitialized) {
val seenMarkVisible = settings.getBoolean("media_seen", true)
videoListAdapter = VideoListAdapter(seenMarkVisible)
+ dataObserver = videoListAdapter.onAnyChange { updateEmptyView() }
multiSelectHelper = videoListAdapter.multiSelectHelper
val folder = if (savedInstanceState != null) savedInstanceState.getParcelable<Folder>(KEY_FOLDER)
else arguments?.getParcelable(KEY_FOLDER)
@@ -236,6 +239,7 @@ class VideoGridFragment : MediaBrowserFragment<VideosViewModel>(), SwipeRefreshL
super.onDestroy()
videoListAdapter.release()
gridItemDecoration = null
+ if (::dataObserver.isInitialized) videoListAdapter.unregisterAdapterDataObserver(dataObserver)
}
override fun getTitle() = when(viewModel.groupingType) {
diff --git a/application/vlc-android/src/org/videolan/vlc/util/Kextensions.kt b/application/vlc-android/src/org/videolan/vlc/util/Kextensions.kt
index 2a04a6131..6c7824c73 100644
--- a/application/vlc-android/src/org/videolan/vlc/util/Kextensions.kt
+++ b/application/vlc-android/src/org/videolan/vlc/util/Kextensions.kt
@@ -25,6 +25,7 @@ import androidx.databinding.BindingAdapter
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.*
+import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.Flow
@@ -218,6 +219,51 @@ fun Context.getPendingIntent(iPlay: Intent): PendingIntent {
else PendingIntent.getService(applicationContext, 0, iPlay, PendingIntent.FLAG_UPDATE_CURRENT)
}
+/**
+ * Register an [RecyclerView.AdapterDataObserver] for the adapter.
+ *
+ * [listener] is called each time a change occurs in the adapter
+ *
+ * return the registered [RecyclerView.AdapterDataObserver]
+ *
+ * /!\ Make sure to unregister [RecyclerView.AdapterDataObserver]
+ */
+fun RecyclerView.Adapter<*>.onAnyChange(listener: ()->Unit): RecyclerView.AdapterDataObserver {
+ val dataObserver = object : RecyclerView.AdapterDataObserver() {
+ override fun onChanged() {
+ super.onChanged()
+ listener.invoke()
+ }
+
+ override fun onItemRangeChanged(positionStart: Int, itemCount: Int) {
+ super.onItemRangeChanged(positionStart, itemCount)
+ listener.invoke()
+ }
+
+ override fun onItemRangeChanged(positionStart: Int, itemCount: Int, payload: Any?) {
+ super.onItemRangeChanged(positionStart, itemCount, payload)
+ listener.invoke()
+ }
+
+ override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
+ super.onItemRangeInserted(positionStart, itemCount)
+ listener.invoke()
+ }
+
+ override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
+ super.onItemRangeMoved(fromPosition, toPosition, itemCount)
+ listener.invoke()
+ }
+
+ override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
+ super.onItemRangeRemoved(positionStart, itemCount)
+ listener.invoke()
+ }
+ }
+ registerAdapterDataObserver(dataObserver)
+ return dataObserver
+}
+
fun generateResolutionClass(width: Int, height: Int) : String? = if (width <= 0 || height <= 0) {
null
} else when {
More information about the Android
mailing list