@@ -10,7 +10,6 @@ package com.owncloud.android.ui.adapter
1010
1111import android.view.Gravity
1212import android.view.View
13- import android.view.ViewGroup
1413import android.widget.FrameLayout
1514import android.widget.ImageView
1615import androidx.core.content.ContextCompat
@@ -20,15 +19,12 @@ import com.elyeproj.loaderviewlibrary.LoaderImageView
2019import com.nextcloud.android.common.ui.theme.utils.ColorRole
2120import com.nextcloud.utils.OCFileUtils
2221import com.nextcloud.utils.extensions.makeRounded
23- import com.nextcloud.utils.extensions.mediaSize
2422import com.nextcloud.utils.extensions.setVisibleIf
2523import com.owncloud.android.R
2624import com.owncloud.android.databinding.GalleryRowBinding
2725import com.owncloud.android.datamodel.FileDataStorageManager
2826import com.owncloud.android.datamodel.GalleryRow
2927import com.owncloud.android.datamodel.OCFile
30- import com.owncloud.android.lib.resources.files.model.ImageDimension
31- import com.owncloud.android.utils.DisplayUtils
3228import com.owncloud.android.utils.theme.ViewThemeUtils
3329
3430@Suppress(" LongParameterList" )
@@ -37,7 +33,7 @@ class GalleryRowHolder(
3733 private val defaultThumbnailSize : Float ,
3834 private val ocFileListDelegate : OCFileListDelegate ,
3935 val storageManager : FileDataStorageManager ,
40- private val galleryAdapter : GalleryAdapter ,
36+ galleryAdapter : GalleryAdapter ,
4137 private val viewThemeUtils : ViewThemeUtils
4238) : SectionedViewHolder(binding.root) {
4339 val context = galleryAdapter.context
@@ -71,25 +67,25 @@ class GalleryRowHolder(
7167 // Only rebuild if file count changed
7268 if (lastFileCount != requiredCount) {
7369 binding.rowLayout.removeAllViews()
74- for (file in row.files) {
75- val rowLayout = getRowLayout(file)
76- binding.rowLayout.addView(rowLayout)
70+ row.files.forEach { file ->
71+ binding.rowLayout.addView(getRowLayout(file))
7772 }
7873 lastFileCount = requiredCount
7974 }
8075
81- val shrinkRatio = computeShrinkRatio (row)
76+ val dimensions = getDimensions (row)
8277
8378 for (i in row.files.indices) {
84- adjustFile(i, row.files[i], shrinkRatio, row)
79+ val dim = dimensions.getOrNull(i) ? : (defaultThumbnailSize.toInt() to defaultThumbnailSize.toInt())
80+ adjustFile(i, row.files[i], dim, row)
8581 }
8682 }
8783
88- fun updateRowVisuals () {
89- bind(currentRow)
90- }
84+ fun updateRowVisuals () = bind(currentRow)
9185
9286 private fun getRowLayout (file : OCFile ): FrameLayout {
87+ val (width, height) = OCFileUtils .getImageSize(file, defaultThumbnailSize)
88+
9389 val checkbox = ImageView (context).apply {
9490 visibility = View .GONE
9591 layoutParams = FrameLayout .LayoutParams (
@@ -102,20 +98,17 @@ class GalleryRowHolder(
10298 }
10399 }
104100
105- val mediaSize = file.mediaSize(defaultThumbnailSize)
106- val (width, height) = mediaSize
107-
108101 val shimmer = LoaderImageView (context).apply {
109102 setImageResource(R .drawable.background)
110103 resetLoader()
111104 layoutParams = FrameLayout .LayoutParams (width, height)
112105 }
113106
114- val drawable = OCFileUtils .getMediaPlaceholder(file, mediaSize )
107+ val drawable = OCFileUtils .getMediaPlaceholder(file, width to height )
115108 val rowCellImageView = ImageView (context).apply {
116109 setImageDrawable(drawable)
117110 adjustViewBounds = true
118- scaleType = ImageView .ScaleType .FIT_XY
111+ scaleType = ImageView .ScaleType .CENTER_CROP
119112 layoutParams = FrameLayout .LayoutParams (width, height)
120113 }
121114
@@ -126,101 +119,66 @@ class GalleryRowHolder(
126119 }
127120 }
128121
129- @SuppressWarnings(" MagicNumber" )
130- private fun computeShrinkRatio (row : GalleryRow ): Float {
131- val screenWidth = DisplayUtils .convertDpToPixel(
132- context.resources.configuration.screenWidthDp.toFloat(),
133- context
134- ).toFloat()
135-
136- return if (row.files.size > 1 ) {
137- computeMultiFileShrinkRatio(row, screenWidth)
138- } else {
139- computeSingleFileShrinkRatio(row, screenWidth)
122+ private fun getDimensions (row : GalleryRow ): List <Pair <Int , Int >> {
123+ val screenWidthPx = context.resources.displayMetrics.widthPixels.toFloat()
124+ val marginPx = smallMargin.toFloat()
125+ val totalMargins = marginPx * (row.files.size - 1 )
126+ val availableWidth = screenWidthPx - totalMargins
127+
128+ val aspectRatios = row.files.map { file ->
129+ val (w, h) = OCFileUtils .getImageSize(file, defaultThumbnailSize)
130+ if (h > 0 ) w.toFloat() / h else 1.0f
140131 }
141- }
142132
143- private fun computeMultiFileShrinkRatio (row : GalleryRow , screenWidth : Float ): Float {
144- val targetHeight = row.getMaxHeight()
145- var totalUnscaledWidth = 0f
133+ val sumAspectRatios = aspectRatios.sum()
146134
147- for (file in row.files) {
148- val (originalWidth, originalHeight) = OCFileUtils .getImageSize(file, defaultThumbnailSize)
135+ // calculate row height based on aspect ratios
136+ val rowHeightFloat = if (sumAspectRatios > 0 ) availableWidth / sumAspectRatios else defaultThumbnailSize
137+ val finalHeight = rowHeightFloat.toInt()
149138
150- val scaledWidth = targetHeight * (originalWidth.toFloat() / originalHeight)
151- file.imageDimension = ImageDimension (scaledWidth, targetHeight)
139+ // for each aspect ratio calculate widths
140+ val finalWidths = aspectRatios.map { ratio -> (rowHeightFloat * ratio).toInt() }.toMutableList()
141+ val usedWidth = finalWidths.sum()
152142
153- totalUnscaledWidth + = scaledWidth
154- }
143+ // based on screen width get remaining pixels
144+ val remainingPixels = (availableWidth - usedWidth).toInt()
155145
156- val totalAvailableWidth = screenWidth - ((row.files.size - 1 ) * smallMargin)
157- return totalAvailableWidth / totalUnscaledWidth
158- }
146+ // add to remaining pixels to last image
147+ if (remainingPixels > 0 && finalWidths.isNotEmpty()) {
148+ val lastIndex = finalWidths.lastIndex
149+ finalWidths[lastIndex] = finalWidths[lastIndex] + remainingPixels
150+ }
159151
160- private fun computeSingleFileShrinkRatio (row : GalleryRow , screenWidth : Float ): Float {
161- val width = OCFileUtils .getImageSize(row.files[0 ], defaultThumbnailSize).first
162- return (screenWidth / galleryAdapter.columns) / width
152+ return finalWidths.map { w -> w to finalHeight }
163153 }
164154
165- private fun adjustFile (index : Int , file : OCFile , shrinkRatio : Float , row : GalleryRow ) {
166- val width = file.imageDimension?.width?.times(shrinkRatio)?.toInt() ? : 0
167- val height = file.imageDimension?.height?.times(shrinkRatio)?.toInt() ? : 0
168-
155+ private fun adjustFile (index : Int , file : OCFile , dims : Pair <Int , Int >, row : GalleryRow ) {
156+ val (width, height) = dims
169157 val frameLayout = binding.rowLayout[index] as FrameLayout
170158 val shimmer = frameLayout[0 ] as LoaderImageView
171159 val thumbnail = frameLayout[1 ] as ImageView
172- val checkBoxImageView = frameLayout[2 ] as ImageView
160+ val checkbox = frameLayout[2 ] as ImageView
173161
174162 val isChecked = ocFileListDelegate.isCheckedFile(file)
175-
176163 adjustRowCell(thumbnail, isChecked)
177- adjustCheckBox(checkBoxImageView, isChecked)
178-
179- ocFileListDelegate.bindGalleryRow(
180- shimmer,
181- thumbnail,
182- file,
183- this ,
184- width to height
185- )
186-
187- // Update layout params only if they differ
188- val thumbLp = thumbnail.layoutParams
189- if (thumbLp.width != width || thumbLp.height != height) {
190- thumbnail.layoutParams = thumbLp.getFrameLayout(width, height).apply {
191- val endMargin = if (index < row.files.size - 1 ) smallMargin else zero
192- this .setMargins(zero, zero, endMargin, smallMargin)
193- }
194- }
164+ adjustCheckBox(checkbox, isChecked)
195165
196- val shimmerLp = shimmer.layoutParams
197- if (shimmerLp.width != width || shimmerLp.height != height) {
198- shimmer.layoutParams = shimmerLp.getFrameLayout(width, height)
199- }
166+ ocFileListDelegate.bindGalleryRow(shimmer, thumbnail, file, this , dims)
200167
201- // Force layout update
168+ val endMargin = if (index < row.files.size - 1 ) smallMargin else zero
169+ thumbnail.layoutParams = FrameLayout .LayoutParams (width, height).apply {
170+ setMargins(0 , 0 , endMargin, smallMargin)
171+ }
172+ shimmer.layoutParams = FrameLayout .LayoutParams (width, height)
202173 frameLayout.requestLayout()
203174 }
204175
205- private fun ViewGroup.LayoutParams?.getFrameLayout (width : Int , height : Int ): FrameLayout .LayoutParams = (
206- this as ? FrameLayout .LayoutParams
207- ? : FrameLayout .LayoutParams (width, height)
208- ).apply {
209- this .width = width
210- this .height = height
211- }
212-
213176 @Suppress(" MagicNumber" )
214177 private fun adjustRowCell (imageView : ImageView , isChecked : Boolean ) {
215178 val scale = if (isChecked) 0.8f else 1.0f
216179 val radius = if (isChecked) iconRadius else 0f
217-
218- // Only update if values changed
219- if (imageView.scaleX != scale) {
220- imageView.scaleX = scale
221- imageView.scaleY = scale
222- }
223-
180+ imageView.scaleX = scale
181+ imageView.scaleY = scale
224182 imageView.makeRounded(context, radius)
225183 }
226184
0 commit comments