@@ -10,6 +10,7 @@ package com.owncloud.android.ui.adapter
1010
1111import android.view.Gravity
1212import android.view.View
13+ import android.view.ViewGroup
1314import android.widget.FrameLayout
1415import android.widget.ImageView
1516import androidx.core.content.ContextCompat
@@ -44,32 +45,55 @@ class GalleryRowHolder(
4445 val context = galleryAdapter.context
4546
4647 private lateinit var currentRow: GalleryRow
48+
49+ // Cached values
4750 private val zero by lazy { context.resources.getInteger(R .integer.zero) }
4851 private val smallMargin by lazy { context.resources.getInteger(R .integer.small_margin) }
4952 private val iconRadius by lazy { context.resources.getDimension(R .dimen.activity_icon_radius) }
5053 private val standardMargin by lazy { context.resources.getDimension(R .dimen.standard_margin) }
5154 private val checkBoxMargin by lazy { context.resources.getDimension(R .dimen.standard_quarter_padding) }
5255
53- fun bind (row : GalleryRow ) {
54- currentRow = row
56+ private val defaultBitmap by lazy {
57+ val fileDrawable = ResourcesCompat .getDrawable(context.resources, R .drawable.file_image, null )
58+ val thumbnailSize = defaultThumbnailSize.toInt()
59+ BitmapUtils .drawableToBitmap(fileDrawable, thumbnailSize, thumbnailSize)
60+ }
5561
56- // re-use existing ones
57- while (binding.rowLayout.childCount < row.files.size) {
58- val rowLayout = getRowLayout()
59- binding.rowLayout.addView(rowLayout)
62+ private val checkedDrawable by lazy {
63+ ContextCompat .getDrawable(context, R .drawable.ic_checkbox_marked)?.also {
64+ viewThemeUtils.platform.tintDrawable(context, it, ColorRole .PRIMARY )
6065 }
66+ }
67+
68+ private val uncheckedDrawable by lazy {
69+ ContextCompat .getDrawable(context, R .drawable.ic_checkbox_blank_outline)
70+ }
6171
62- if (binding.rowLayout.childCount > row.files.size) {
63- binding.rowLayout.removeViews(row.files.size, binding.rowLayout.childCount - row.files.size)
72+ private var lastFileCount = - 1
73+ // endregion
74+
75+ fun bind (row : GalleryRow ) {
76+ currentRow = row
77+ val requiredCount = row.files.size
78+
79+ // Only rebuild if file count changed
80+ if (lastFileCount != requiredCount) {
81+ binding.rowLayout.removeAllViews()
82+ repeat(requiredCount) { binding.rowLayout.addView(getRowLayout()) }
83+ lastFileCount = requiredCount
6484 }
6585
6686 val shrinkRatio = computeShrinkRatio(row)
6787
68- for (indexedFile in row.files.withIndex() ) {
69- adjustFile(indexedFile , shrinkRatio, row)
88+ for (i in row.files.indices ) {
89+ adjustFile(i, row.files[i] , shrinkRatio, row)
7090 }
7191 }
7292
93+ fun updateRowVisuals () {
94+ bind(currentRow)
95+ }
96+
7397 private fun getRowLayout (): FrameLayout {
7498 val checkbox = ImageView (context).apply {
7599 visibility = View .GONE
@@ -89,16 +113,15 @@ class GalleryRowHolder(
89113 invalidate()
90114 }
91115
92- val fileDrawable = ResourcesCompat .getDrawable(context.resources, R .drawable.file_image, null )
93- val thumbnailSize = defaultThumbnailSize.toInt()
94- val bitmap = BitmapUtils .drawableToBitmap(fileDrawable, thumbnailSize, thumbnailSize)
95116 val drawable = ThumbnailsCacheManager .AsyncGalleryImageDrawable (
96117 context.resources,
97- bitmap ,
118+ defaultBitmap ,
98119 null
99120 )
100121 val rowCellImageView = ImageView (context).apply {
101122 setImageDrawable(drawable)
123+ adjustViewBounds = true
124+ scaleType = ImageView .ScaleType .FIT_XY
102125 }
103126
104127 return FrameLayout (context).apply {
@@ -108,10 +131,6 @@ class GalleryRowHolder(
108131 }
109132 }
110133
111- fun redraw () {
112- bind(currentRow)
113- }
114-
115134 @SuppressWarnings(" MagicNumber" )
116135 private fun computeShrinkRatio (row : GalleryRow ): Float {
117136 val screenWidth = DisplayUtils .convertDpToPixel(
@@ -148,20 +167,14 @@ class GalleryRowHolder(
148167 return (screenWidth / galleryAdapter.columns) / width
149168 }
150169
151- private fun adjustFile (indexedFile : IndexedValue <OCFile >, shrinkRatio : Float , row : GalleryRow ) {
152- val file = indexedFile.value
153- val index = indexedFile.index
154-
170+ private fun adjustFile (index : Int , file : OCFile , shrinkRatio : Float , row : GalleryRow ) {
155171 val width = file.imageDimension?.width?.times(shrinkRatio)?.toInt() ? : 0
156172 val height = file.imageDimension?.height?.times(shrinkRatio)?.toInt() ? : 0
157173
158174 val frameLayout = binding.rowLayout[index] as FrameLayout
159- val checkBoxImageView = frameLayout[2 ] as ImageView
160175 val shimmer = frameLayout[0 ] as LoaderImageView
161- val thumbnail = (frameLayout[1 ] as ImageView ).apply {
162- adjustViewBounds = true
163- scaleType = ImageView .ScaleType .FIT_XY
164- }
176+ val thumbnail = frameLayout[1 ] as ImageView
177+ val checkBoxImageView = frameLayout[2 ] as ImageView
165178
166179 val isChecked = ocFileListDelegate.isCheckedFile(file)
167180
@@ -176,43 +189,59 @@ class GalleryRowHolder(
176189 width
177190 )
178191
192+ // Update layout params only if they differ
193+ val thumbLp = thumbnail.layoutParams
194+ if (thumbLp.width != width || thumbLp.height != height) {
195+ thumbnail.layoutParams = thumbLp.getFrameLayout(width, height).apply {
196+ val endMargin = if (index < row.files.size - 1 ) smallMargin else zero
197+ this .setMargins(zero, zero, endMargin, smallMargin)
198+ }
199+ }
200+
201+ val shimmerLp = shimmer.layoutParams
202+ if (shimmerLp.width != width || shimmerLp.height != height) {
203+ shimmer.layoutParams = shimmerLp.getFrameLayout(width, height)
204+ }
205+
179206 // Force layout update
180207 frameLayout.requestLayout()
208+ }
181209
182- val params = FrameLayout .LayoutParams (width, height)
183- val endMargin = if (index < row.files.size - 1 ) smallMargin else zero
184- params.setMargins(zero, zero, endMargin, smallMargin )
185-
186- thumbnail.layoutParams = params
187- shimmer.layoutParams = FrameLayout . LayoutParams (params)
210+ private fun ViewGroup .LayoutParams?. getFrameLayout (width : Int , height : Int ): FrameLayout . LayoutParams = (
211+ this as ? FrameLayout . LayoutParams
212+ ? : FrameLayout . LayoutParams (width, height )
213+ ). apply {
214+ this .width = width
215+ this .height = height
188216 }
189217
190218 @Suppress(" MagicNumber" )
191219 private fun adjustRowCell (imageView : ImageView , isChecked : Boolean ) {
192- imageView.apply {
193- scaleX = if (isChecked) 0.8f else 1.0f
194- scaleY = scaleX
195- makeRounded(context, if (isChecked) iconRadius else 0f )
220+ val scale = if (isChecked) 0.8f else 1.0f
221+ val radius = if (isChecked) iconRadius else 0f
222+
223+ // Only update if values changed
224+ if (imageView.scaleX != scale) {
225+ imageView.scaleX = scale
226+ imageView.scaleY = scale
196227 }
228+
229+ imageView.makeRounded(context, radius)
197230 }
198231
199232 private fun adjustCheckBox (imageView : ImageView , isChecked : Boolean ) {
200233 if (ocFileListDelegate.isMultiSelect) {
201- val checkboxDrawable = (
202- if (isChecked) {
203- val drawable = ContextCompat .getDrawable(context, R .drawable.ic_checkbox_marked)
204- drawable?.let {
205- viewThemeUtils.platform.tintDrawable(context, drawable, ColorRole .PRIMARY )
206- }
207- drawable
208- } else {
209- ContextCompat .getDrawable(context, R .drawable.ic_checkbox_blank_outline)
210- }
211- )?.apply {
234+ val checkboxDrawable = if (isChecked) checkedDrawable else uncheckedDrawable
235+
236+ checkboxDrawable?.apply {
212237 val margin = standardMargin.toInt()
213238 setBounds(margin, margin, margin, margin)
214239 }
215- imageView.setImageDrawable(checkboxDrawable)
240+
241+ // Only set if different
242+ if (imageView.drawable != = checkboxDrawable) {
243+ imageView.setImageDrawable(checkboxDrawable)
244+ }
216245 }
217246
218247 imageView.setVisibleIf(ocFileListDelegate.isMultiSelect)
0 commit comments