mirror of
https://github.com/FossifyOrg/Gallery.git
synced 2024-11-22 04:28:00 +01:00
Rely solely on recyclerview for lazy loading
Closes https://github.com/FossifyOrg/Gallery/issues/136 - Remove manual lazy loading mechanism - Disable cross fade when loading from cache
This commit is contained in:
parent
85f5f43b29
commit
ff836d8c24
3 changed files with 37 additions and 69 deletions
|
@ -4,8 +4,6 @@ import android.content.Intent
|
|||
import android.content.pm.ShortcutInfo
|
||||
import android.content.pm.ShortcutManager
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
@ -38,11 +36,8 @@ import org.fossify.gallery.models.ThumbnailSection
|
|||
class MediaAdapter(
|
||||
activity: BaseSimpleActivity, var media: ArrayList<ThumbnailItem>, val listener: MediaOperationsListener?, val isAGetIntent: Boolean,
|
||||
val allowMultiplePicks: Boolean, val path: String, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit
|
||||
) :
|
||||
MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate {
|
||||
) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate {
|
||||
|
||||
private val INSTANT_LOAD_DURATION = 2000L
|
||||
private val IMAGE_LOAD_DELAY = 100L
|
||||
private val ITEM_SECTION = 0
|
||||
private val ITEM_MEDIUM_VIDEO_PORTRAIT = 1
|
||||
private val ITEM_MEDIUM_PHOTO = 2
|
||||
|
@ -50,10 +45,7 @@ class MediaAdapter(
|
|||
private val config = activity.config
|
||||
private val viewType = config.getFolderViewType(if (config.showAll) SHOW_ALL else path)
|
||||
private val isListViewType = viewType == VIEW_TYPE_LIST
|
||||
private var visibleItemPaths = ArrayList<String>()
|
||||
private var rotatedImagePaths = ArrayList<String>()
|
||||
private var loadImageInstantly = false
|
||||
private var delayHandler = Handler(Looper.getMainLooper())
|
||||
private var currentMediaHash = media.hashCode()
|
||||
private val hasOTGConnected = activity.hasOTGConnected()
|
||||
|
||||
|
@ -69,7 +61,6 @@ class MediaAdapter(
|
|||
|
||||
init {
|
||||
setupDragListener(true)
|
||||
enableInstantLoad()
|
||||
}
|
||||
|
||||
override fun getActionMenuId() = R.menu.cab_media
|
||||
|
@ -97,10 +88,6 @@ class MediaAdapter(
|
|||
|
||||
override fun onBindViewHolder(holder: MyRecyclerViewAdapter.ViewHolder, position: Int) {
|
||||
val tmbItem = media.getOrNull(position) ?: return
|
||||
if (tmbItem is Medium) {
|
||||
visibleItemPaths.add(tmbItem.path)
|
||||
}
|
||||
|
||||
val allowLongPress = (!isAGetIntent || allowMultiplePicks) && tmbItem is Medium
|
||||
holder.bindView(tmbItem, tmbItem is Medium, allowLongPress) { itemView, adapterPosition ->
|
||||
if (tmbItem is Medium) {
|
||||
|
@ -197,7 +184,6 @@ class MediaAdapter(
|
|||
super.onViewRecycled(holder)
|
||||
if (!activity.isDestroyed) {
|
||||
val itemView = holder.itemView
|
||||
visibleItemPaths.remove(itemView.allViews.firstOrNull { it.id == R.id.medium_name }?.tag)
|
||||
val tmb = itemView.allViews.firstOrNull { it.id == R.id.medium_thumbnail }
|
||||
if (tmb != null) {
|
||||
Glide.with(activity).clear(tmb)
|
||||
|
@ -254,7 +240,6 @@ class MediaAdapter(
|
|||
activity.updateDBMediaPath(firstPath, it)
|
||||
|
||||
activity.runOnUiThread {
|
||||
enableInstantLoad()
|
||||
listener?.refreshItems()
|
||||
finishActMode()
|
||||
}
|
||||
|
@ -262,7 +247,6 @@ class MediaAdapter(
|
|||
}
|
||||
} else {
|
||||
RenameDialog(activity, getSelectedPaths(), true) {
|
||||
enableInstantLoad()
|
||||
listener?.refreshItems()
|
||||
finishActMode()
|
||||
}
|
||||
|
@ -572,7 +556,6 @@ class MediaAdapter(
|
|||
if (thumbnailItems.hashCode() != currentMediaHash) {
|
||||
currentMediaHash = thumbnailItems.hashCode()
|
||||
media = thumbnailItems
|
||||
enableInstantLoad()
|
||||
notifyDataSetChanged()
|
||||
finishActMode()
|
||||
}
|
||||
|
@ -580,7 +563,6 @@ class MediaAdapter(
|
|||
|
||||
fun updateDisplayFilenames(displayFilenames: Boolean) {
|
||||
this.displayFilenames = displayFilenames
|
||||
enableInstantLoad()
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
|
@ -599,13 +581,6 @@ class MediaAdapter(
|
|||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
private fun enableInstantLoad() {
|
||||
loadImageInstantly = true
|
||||
delayHandler.postDelayed({
|
||||
loadImageInstantly = false
|
||||
}, INSTANT_LOAD_DURATION)
|
||||
}
|
||||
|
||||
private fun setupThumbnail(view: View, medium: Medium) {
|
||||
val isSelected = selectedKeys.contains(medium.path.hashCode())
|
||||
bindItem(view, medium).apply {
|
||||
|
@ -681,46 +656,21 @@ class MediaAdapter(
|
|||
else -> ROUNDED_CORNERS_NONE
|
||||
}
|
||||
|
||||
if (loadImageInstantly) {
|
||||
activity.loadImage(
|
||||
type = medium.type,
|
||||
path = path,
|
||||
target = mediumThumbnail,
|
||||
horizontalScroll = scrollHorizontally,
|
||||
animateGifs = animateGifs,
|
||||
cropThumbnails = cropThumbnails,
|
||||
roundCorners = roundedCorners,
|
||||
signature = medium.getKey(),
|
||||
skipMemoryCacheAtPaths = rotatedImagePaths,
|
||||
onError = {
|
||||
mediumThumbnail.scaleType = ImageView.ScaleType.CENTER
|
||||
mediumThumbnail.setImageDrawable(AppCompatResources.getDrawable(activity, R.drawable.ic_vector_warning_colored))
|
||||
}
|
||||
)
|
||||
} else {
|
||||
mediumThumbnail.setImageDrawable(null)
|
||||
mediumThumbnail.isHorizontalScrolling = scrollHorizontally
|
||||
delayHandler.postDelayed({
|
||||
val isVisible = visibleItemPaths.contains(medium.path)
|
||||
if (isVisible) {
|
||||
activity.loadImage(
|
||||
type = medium.type,
|
||||
path = path,
|
||||
target = mediumThumbnail,
|
||||
horizontalScroll = scrollHorizontally,
|
||||
animateGifs = animateGifs,
|
||||
cropThumbnails = cropThumbnails,
|
||||
roundCorners = roundedCorners,
|
||||
signature = medium.getKey(),
|
||||
skipMemoryCacheAtPaths = rotatedImagePaths,
|
||||
onError = {
|
||||
mediumThumbnail.scaleType = ImageView.ScaleType.CENTER
|
||||
mediumThumbnail.setImageDrawable(AppCompatResources.getDrawable(activity, R.drawable.ic_vector_warning_colored))
|
||||
}
|
||||
)
|
||||
}
|
||||
}, IMAGE_LOAD_DELAY)
|
||||
}
|
||||
activity.loadImage(
|
||||
type = medium.type,
|
||||
path = path,
|
||||
target = mediumThumbnail,
|
||||
horizontalScroll = scrollHorizontally,
|
||||
animateGifs = animateGifs,
|
||||
cropThumbnails = cropThumbnails,
|
||||
roundCorners = roundedCorners,
|
||||
signature = medium.getKey(),
|
||||
skipMemoryCacheAtPaths = rotatedImagePaths,
|
||||
onError = {
|
||||
mediumThumbnail.scaleType = ImageView.ScaleType.CENTER
|
||||
mediumThumbnail.setImageDrawable(AppCompatResources.getDrawable(activity, R.drawable.ic_vector_warning_colored))
|
||||
}
|
||||
)
|
||||
|
||||
if (isListViewType) {
|
||||
mediumName.setTextColor(textColor)
|
||||
|
|
|
@ -28,7 +28,6 @@ import com.bumptech.glide.load.engine.GlideException
|
|||
import com.bumptech.glide.load.resource.bitmap.CenterCrop
|
||||
import com.bumptech.glide.load.resource.bitmap.FitCenter
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
import com.bumptech.glide.request.target.Target
|
||||
|
@ -586,7 +585,7 @@ fun Context.loadImageBase(
|
|||
.load(path)
|
||||
.apply(options)
|
||||
.set(WebpDownsampler.USE_SYSTEM_DECODER, false) // CVE-2023-4863
|
||||
.transition(DrawableTransitionOptions.withCrossFade(crossFadeDuration))
|
||||
.transition(getOptionalCrossFadeTransition(crossFadeDuration))
|
||||
|
||||
builder = builder.listener(object : RequestListener<Drawable> {
|
||||
override fun onLoadFailed(e: GlideException?, model: Any?, targetBitmap: Target<Drawable>, isFirstResource: Boolean): Boolean {
|
||||
|
@ -627,7 +626,7 @@ fun Context.loadSVG(
|
|||
.listener(SvgSoftwareLayerSetter())
|
||||
.load(path)
|
||||
.apply(options)
|
||||
.transition(DrawableTransitionOptions.withCrossFade(crossFadeDuration))
|
||||
.transition(getOptionalCrossFadeTransition(crossFadeDuration))
|
||||
|
||||
if (roundCorners != ROUNDED_CORNERS_NONE) {
|
||||
val cornerSize =
|
||||
|
|
19
app/src/main/kotlin/org/fossify/gallery/extensions/Glide.kt
Normal file
19
app/src/main/kotlin/org/fossify/gallery/extensions/Glide.kt
Normal file
|
@ -0,0 +1,19 @@
|
|||
package org.fossify.gallery.extensions
|
||||
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||
import com.bumptech.glide.request.transition.DrawableCrossFadeFactory
|
||||
import com.bumptech.glide.request.transition.TransitionFactory
|
||||
|
||||
/**
|
||||
* Cross fade transition option that disabled fading when loading from cache.
|
||||
*/
|
||||
fun getOptionalCrossFadeTransition(duration: Int): DrawableTransitionOptions {
|
||||
return DrawableTransitionOptions.with(
|
||||
TransitionFactory { dataSource, isFirstResource ->
|
||||
if (dataSource == DataSource.RESOURCE_DISK_CACHE) return@TransitionFactory null
|
||||
DrawableCrossFadeFactory.Builder(duration).build().build(dataSource, isFirstResource)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in a new issue