From 6533ecd576f5497f4378e5e38a2e0afdaa0909fc Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Fri, 30 Oct 2026 17:01:20 +0300 Subject: [PATCH] fix(file-list): flicker Signed-off-by: alperozturk96 --- .../android/ui/adapter/GalleryAdapter.kt | 3 ++- .../CommonOCFileListAdapterInterface.kt | 3 ++- .../ui/adapter/filelist/OCFileListAdapter.kt | 19 +++++++++++-------- .../adapter/filelist/data/OCFileListDiffer.kt | 13 +++++++++++++ .../filelist/item/OCFileListDelegate.kt | 2 +- .../android/ui/fragment/OCFileListFragment.kt | 10 ++++++---- 6 files changed, 35 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/GalleryAdapter.kt b/app/src/main/java/com/owncloud/android/ui/adapter/GalleryAdapter.kt index 3b3406503203..5da4f6539ebb 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/GalleryAdapter.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/GalleryAdapter.kt @@ -387,7 +387,8 @@ class GalleryAdapter( directory: OCFile, storageManager: FileDataStorageManager, onlyOnDevice: Boolean, - mLimitToMimeType: String + mLimitToMimeType: String, + onSwapped: () -> Unit ) = Unit override fun setHighlightedItem(file: OCFile) = Unit diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/CommonOCFileListAdapterInterface.kt b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/CommonOCFileListAdapterInterface.kt index 8e04cb8054fa..63c56b599eb5 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/CommonOCFileListAdapterInterface.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/CommonOCFileListAdapterInterface.kt @@ -21,7 +21,8 @@ interface CommonOCFileListAdapterInterface { directory: OCFile, storageManager: FileDataStorageManager, onlyOnDevice: Boolean, - mLimitToMimeType: String + mLimitToMimeType: String, + onSwapped: () -> Unit = {} ) fun setHighlightedItem(file: OCFile) diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/OCFileListAdapter.kt b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/OCFileListAdapter.kt index 4a1db86037aa..ffc32e108c7b 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/OCFileListAdapter.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/OCFileListAdapter.kt @@ -91,7 +91,7 @@ class OCFileListAdapter( transferServiceGetter: ComponentsGetter, ocFileListFragmentInterface: OCFileListFragmentInterface, private val hideItemOptions: Boolean, - private var gridView: Boolean, + gridView: Boolean, viewThemeUtils: ViewThemeUtils, private val thumbnailGenerator: ThumbnailGenerator, avatarGenerator: AvatarGenerator @@ -208,7 +208,7 @@ class OCFileListAdapter( OCFileListViewType.HEADER -> OCFileListHeaderViewHolder(ListHeaderBinding.inflate(inflater, parent, false)) - OCFileListViewType.ITEM, OCFileListViewType.IMAGE -> if (gridView) { + OCFileListViewType.ITEM, OCFileListViewType.IMAGE -> if (ocFileListDelegate.gridView) { OCFileListGridItemViewHolder(GridItemBinding.inflate(inflater, parent, false)) } else { OCFileListItemViewHolder(ListItemBinding.inflate(inflater, parent, false)) @@ -279,7 +279,8 @@ class OCFileListAdapter( directory: OCFile, storageManager: FileDataStorageManager, onlyOnDevice: Boolean, - mLimitToMimeType: String + mLimitToMimeType: String, + onSwapped: () -> Unit ) { this.onlyOnDevice = onlyOnDevice @@ -300,7 +301,7 @@ class OCFileListAdapter( preferences, accountUserId ) { newList, _ -> - updateAdapter(newList, directory) + updateAdapter(newList, directory, onSwapped) } } @@ -388,7 +389,7 @@ class OCFileListAdapter( ) } - fun updateAdapter(newFiles: List, directory: OCFile?) { + fun updateAdapter(newFiles: List, directory: OCFile?, onUpdated: () -> Unit = {}) { Log_OC.d(TAG, "updating the adapter") allFiles.clear() @@ -408,8 +409,10 @@ class OCFileListAdapter( if (isSameDirectoryRefresh) { differ.submitAndRebind(files) } else { - differ.replace(files) + differ.replaceWithoutAnimation(files) } + + onUpdated() } } @@ -570,7 +573,7 @@ class OCFileListAdapter( } fun setGridView(bool: Boolean) { - gridView = bool + ocFileListDelegate.gridView = bool } fun setShowMetadata(bool: Boolean) { @@ -639,7 +642,7 @@ class OCFileListAdapter( holder.fileFeaturesLayout?.setVisibleIf(holder.hasVisibleFeatureIndicators) } - private fun shouldShowItemOptions(): Boolean = !(isMultiSelect() || gridView || hideItemOptions) + private fun shouldShowItemOptions(): Boolean = !(isMultiSelect() || ocFileListDelegate.gridView || hideItemOptions) private fun bindMoreOptionsVisibility(holder: ListViewHolder) { val showMoreOptions = !isMultiSelect() && !OCFileListFragment.isMultipleFileSelectedForCopyOrMove diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/data/OCFileListDiffer.kt b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/data/OCFileListDiffer.kt index 708ed108f3bd..d687123face8 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/data/OCFileListDiffer.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/data/OCFileListDiffer.kt @@ -7,6 +7,7 @@ package com.owncloud.android.ui.adapter.filelist.data import android.annotation.SuppressLint +import androidx.core.view.doOnNextLayout import androidx.recyclerview.widget.AsyncDifferConfig import androidx.recyclerview.widget.AsyncListDiffer import androidx.recyclerview.widget.ListUpdateCallback @@ -94,6 +95,11 @@ class OCFileListDiffer( adapter.notifyDataSetChanged() } + fun replaceWithoutAnimation(newFiles: List) { + suppressItemAnimationsUntilNextLayout() + replace(newFiles) + } + fun sortForCurrentView( files: MutableList, searchType: SearchType?, @@ -141,6 +147,13 @@ class OCFileListDiffer( recyclerView = null } + private fun suppressItemAnimationsUntilNextLayout() { + val recyclerView = recyclerView ?: return + val itemAnimator = recyclerView.itemAnimator ?: return + recyclerView.itemAnimator = null + recyclerView.doOnNextLayout { recyclerView.itemAnimator = itemAnimator } + } + private fun keepTopVisibleWhile(adapterPosition: Int, notify: () -> Unit) { val wasAtTop = adapterPosition == 0 && recyclerView?.canScrollVertically(-1) == false notify() diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListDelegate.kt b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListDelegate.kt index 5d603aba1461..82d7b4a8b290 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListDelegate.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/filelist/item/OCFileListDelegate.kt @@ -63,7 +63,7 @@ class OCFileListDelegate( private val user: User, private val storageManager: FileDataStorageManager, private val hideItemOptions: Boolean, - private val gridView: Boolean, + var gridView: Boolean, private val transferServiceGetter: ComponentsGetter, private val showMetadata: Boolean, private var showShareAvatar: Boolean, diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.kt b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.kt index 01f945d5f4bb..3da372fa843d 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.kt +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.kt @@ -1151,12 +1151,15 @@ open class OCFileListFragment : } Log_OC.i(TAG, "Listing directory ${directoryToList.decryptedRemotePath}, onlyOnDevice=$onlyOnDevice") - adapter.swapDirectory(accountManager.user, directoryToList, storageManager, onlyOnDevice, mimeType) - val previousDirectory = currentFile + adapter.swapDirectory(accountManager.user, directoryToList, storageManager, onlyOnDevice, mimeType) { + if (view == null) return@swapDirectory + fileListLayoutManager?.setLayoutViewMode() + scrollToHighlightedFileOrTop(adapter, highlightedFile, previousDirectory, directoryToList) + } + currentFile = directoryToList updateUiForCurrentFolder() - scrollToHighlightedFileOrTop(adapter, highlightedFile, previousDirectory, directoryToList) } private fun scrollToHighlightedFileOrTop( @@ -1207,7 +1210,6 @@ open class OCFileListFragment : get() = adapter?.isEmpty ?: true private fun updateUiForCurrentFolder() { - fileListLayoutManager?.setLayoutViewMode() updateSortButtonLabel() setLayoutSwitchButton()