[Android] Restore the lists position upon activity recreation by using stateRestorationPolicy
Nicolas Pomepuy
git at videolan.org
Mon May 9 11:39:03 UTC 2022
vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Fri May 6 13:26:39 2022 +0200| [13303be32d9e2f059eb5d433f626c48168976662] | committer: Duncan McNamara
Restore the lists position upon activity recreation by using stateRestorationPolicy
Fixes #2508
> https://code.videolan.org/videolan/vlc-android/commit/13303be32d9e2f059eb5d433f626c48168976662
---
.../src/org/videolan/vlc/gui/HistoryFragment.kt | 2 +-
.../org/videolan/vlc/gui/audio/AudioBrowserFragment.kt | 8 ++++----
.../videolan/vlc/gui/browser/BaseBrowserFragment.kt | 18 +++++-------------
.../org/videolan/vlc/gui/video/VideoGridFragment.kt | 6 ++++--
4 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/HistoryFragment.kt b/application/vlc-android/src/org/videolan/vlc/gui/HistoryFragment.kt
index 6cd76cbbb..525a4eafa 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/HistoryFragment.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/HistoryFragment.kt
@@ -52,7 +52,7 @@ class HistoryFragment : MediaBrowserFragment<HistoryModel>(), IRefreshable, IHis
private lateinit var cleanMenuItem: MenuItem
private lateinit var multiSelectHelper: MultiSelectHelper<MediaWrapper>
- private val historyAdapter: HistoryAdapter = HistoryAdapter(listEventsHandler = this)
+ private val historyAdapter: HistoryAdapter = HistoryAdapter(listEventsHandler = this).apply { stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY }
private lateinit var itemTouchHelper: ItemTouchHelper
private lateinit var list: RecyclerView
private lateinit var empty: TextView
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.kt b/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.kt
index f13b3f214..deb5ab993 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.kt
@@ -180,10 +180,10 @@ class AudioBrowserFragment : BaseAudioBrowser<AudioBrowserViewModel>() {
viewModel = getViewModel()
currentTab = viewModel.currentTab
- artistsAdapter = AudioBrowserAdapter(MediaLibraryItem.TYPE_ARTIST, this)
- albumsAdapter = AudioBrowserAdapter(MediaLibraryItem.TYPE_ALBUM, this)
- songsAdapter = AudioBrowserAdapter(MediaLibraryItem.TYPE_MEDIA, this)
- genresAdapter = AudioBrowserAdapter(MediaLibraryItem.TYPE_GENRE, this)
+ artistsAdapter = AudioBrowserAdapter(MediaLibraryItem.TYPE_ARTIST, this).apply { stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY }
+ albumsAdapter = AudioBrowserAdapter(MediaLibraryItem.TYPE_ALBUM, this).apply { stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY }
+ songsAdapter = AudioBrowserAdapter(MediaLibraryItem.TYPE_MEDIA, this).apply { stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY }
+ genresAdapter = AudioBrowserAdapter(MediaLibraryItem.TYPE_GENRE, this).apply { stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY }
adapters = arrayOf(artistsAdapter, albumsAdapter, songsAdapter, genresAdapter)
setupProvider()
}
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.kt b/application/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.kt
index 4d833124c..8916e6bd7 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.kt
@@ -50,7 +50,10 @@ import org.videolan.vlc.BuildConfig
import org.videolan.vlc.R
import org.videolan.vlc.databinding.DirectoryBrowserBinding
import org.videolan.vlc.gui.AudioPlayerContainerActivity
-import org.videolan.vlc.gui.dialogs.*
+import org.videolan.vlc.gui.dialogs.ConfirmDeleteDialog
+import org.videolan.vlc.gui.dialogs.CtxActionReceiver
+import org.videolan.vlc.gui.dialogs.SavePlaylistDialog
+import org.videolan.vlc.gui.dialogs.showContext
import org.videolan.vlc.gui.helpers.MedialibraryUtils
import org.videolan.vlc.gui.helpers.UiTools
import org.videolan.vlc.gui.helpers.UiTools.addToPlaylist
@@ -72,7 +75,6 @@ import java.util.*
private const val TAG = "VLC/BaseBrowserFragment"
internal const val KEY_MEDIA = "key_media"
-private const val KEY_POSITION = "key_list"
const val KEY_PICKER_TYPE = "key_picker_type"
private const val MSG_SHOW_LOADING = 0
internal const val MSG_HIDE_LOADING = 1
@@ -87,7 +89,6 @@ abstract class BaseBrowserFragment : MediaBrowserFragment<BrowserModel>(), IRefr
private lateinit var layoutManager: LinearLayoutManager
override var mrl: String? = null
protected var currentMedia: MediaWrapper? = null
- private var savedPosition = -1
override var isRootDirectory: Boolean = false
override val scannedDirectory = false
override val inCards = false
@@ -109,7 +110,6 @@ abstract class BaseBrowserFragment : MediaBrowserFragment<BrowserModel>(), IRefr
if (bundle != null) {
currentMedia = bundle.getParcelable(KEY_MEDIA)
mrl = currentMedia?.location ?: bundle.getString(KEY_MRL)
- savedPosition = bundle.getInt(KEY_POSITION)
} else if (requireActivity().intent != null) {
mrl = requireActivity().intent.dataString
requireActivity().intent = null
@@ -145,7 +145,7 @@ abstract class BaseBrowserFragment : MediaBrowserFragment<BrowserModel>(), IRefr
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
- if (!this::adapter.isInitialized) adapter = BaseBrowserAdapter(this)
+ if (!this::adapter.isInitialized) adapter = BaseBrowserAdapter(this).apply { stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY }
layoutManager = LinearLayoutManager(activity)
binding.networkList.layoutManager = layoutManager
binding.networkList.adapter = adapter
@@ -225,7 +225,6 @@ abstract class BaseBrowserFragment : MediaBrowserFragment<BrowserModel>(), IRefr
override fun onSaveInstanceState(outState: Bundle) {
outState.putString(KEY_MRL, mrl)
outState.putParcelable(KEY_MEDIA, currentMedia)
- outState.putInt(KEY_POSITION, if (::layoutManager.isInitialized) layoutManager.findFirstCompletelyVisibleItemPosition() else 0)
super.onSaveInstanceState(outState)
}
@@ -271,7 +270,6 @@ abstract class BaseBrowserFragment : MediaBrowserFragment<BrowserModel>(), IRefr
}
override fun onRefresh() {
- savedPosition = layoutManager.findFirstCompletelyVisibleItemPosition()
viewModel.refresh()
}
@@ -599,12 +597,6 @@ abstract class BaseBrowserFragment : MediaBrowserFragment<BrowserModel>(), IRefr
swipeRefreshLayout.isRefreshing = false
handler.sendEmptyMessage(MSG_HIDE_LOADING)
updateEmptyView()
- if (!viewModel.isEmpty()) {
- if (savedPosition > 0) {
- layoutManager.scrollToPositionWithOffset(savedPosition, 0)
- savedPosition = 0
- }
- }
if (!isRootDirectory) {
updateFab()
UiTools.updateSortTitles(this)
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 c0d0be2cc..e198dce9e 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
@@ -37,8 +37,10 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.floatingactionbutton.FloatingActionButton
-import kotlinx.coroutines.*
+import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
import org.videolan.medialibrary.interfaces.Medialibrary
import org.videolan.medialibrary.interfaces.media.Folder
import org.videolan.medialibrary.interfaces.media.MediaWrapper
@@ -100,7 +102,7 @@ class VideoGridFragment : MediaBrowserFragment<VideosViewModel>(), SwipeRefreshL
if (!::settings.isInitialized) settings = Settings.getInstance(requireContext())
if (!::videoListAdapter.isInitialized) {
val seenMarkVisible = settings.getBoolean("media_seen", true)
- videoListAdapter = VideoListAdapter(seenMarkVisible)
+ videoListAdapter = VideoListAdapter(seenMarkVisible).apply { stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY }
dataObserver = videoListAdapter.onAnyChange {
updateEmptyView()
if (::binding.isInitialized) binding.fastScroller.setRecyclerView(binding.videoGrid, viewModel.provider)
More information about the Android
mailing list