diff options
| author | 2023-04-13 18:45:10 -0700 | |
|---|---|---|
| committer | 2023-04-17 14:35:44 -0700 | |
| commit | 2783dd19f19bcbb523fa15e2d8154174f0978479 (patch) | |
| tree | 9252a5b054c08589930e6678297920f17a3d2dfa /java/src | |
| parent | 5c05904fbda5a7d8b0b3a1d474ab7224adb686ee (diff) | |
Constraint image preivew width by Chooser width
Limit preivew aspect ratio so they are never wider than Sharesheet.
Bug: 277629860
Test: manual testing
Test: integration test
Change-Id: I501ffae9287eb524b466d6f654d4d604f97e1883
Diffstat (limited to 'java/src')
| -rw-r--r-- | java/src/com/android/intentresolver/widget/ScrollableImagePreviewView.kt | 70 |
1 files changed, 49 insertions, 21 deletions
diff --git a/java/src/com/android/intentresolver/widget/ScrollableImagePreviewView.kt b/java/src/com/android/intentresolver/widget/ScrollableImagePreviewView.kt index 524b4f81..e760e6d0 100644 --- a/java/src/com/android/intentresolver/widget/ScrollableImagePreviewView.kt +++ b/java/src/com/android/intentresolver/widget/ScrollableImagePreviewView.kt @@ -78,7 +78,7 @@ class ScrollableImagePreviewView : RecyclerView, ImagePreviewView { TypedValue.COMPLEX_UNIT_DIP, 3f, context.resources.displayMetrics ).toInt() } - var outerSpacing = a.getDimensionPixelSize( + outerSpacing = a.getDimensionPixelSize( R.styleable.ScrollableImagePreviewView_itemOuterSpacing, -1 ) if (outerSpacing < 0) { @@ -104,12 +104,24 @@ class ScrollableImagePreviewView : RecyclerView, ImagePreviewView { var maxWidthHint: Int = -1 private var requestedHeight: Int = 0 private var isMeasured = false + private var maxAspectRatio = MAX_ASPECT_RATIO + private var maxAspectRatioString = MAX_ASPECT_RATIO_STRING + private var outerSpacing: Int = 0 override fun onMeasure(widthSpec: Int, heightSpec: Int) { super.onMeasure(widthSpec, heightSpec) if (!isMeasured) { isMeasured = true - batchLoader?.loadAspectRatios(getMaxWidth(), this::calcPreviewWidth) + updateMaxWidthHint(widthSpec) + updateMaxAspectRatio() + batchLoader?.loadAspectRatios(getMaxWidth(), this::updatePreviewSize) + } + } + + private fun updateMaxWidthHint(widthSpec: Int) { + if (maxWidthHint > 0) return + if (View.MeasureSpec.getMode(widthSpec) != View.MeasureSpec.UNSPECIFIED) { + maxWidthHint = View.MeasureSpec.getSize(widthSpec) } } @@ -146,7 +158,7 @@ class ScrollableImagePreviewView : RecyclerView, ImagePreviewView { } .apply { if (isMeasured) { - loadAspectRatios(getMaxWidth(), this@ScrollableImagePreviewView::calcPreviewWidth) + loadAspectRatios(getMaxWidth(), this@ScrollableImagePreviewView::updatePreviewSize) } } } @@ -160,14 +172,39 @@ class ScrollableImagePreviewView : RecyclerView, ImagePreviewView { else -> measuredWidth } - private fun calcPreviewWidth(bitmap: Bitmap): Int { + private fun updateMaxAspectRatio() { + val padding = outerSpacing * 2 + val w = maxOf(padding, getMaxWidth() - padding) + val h = if (isLaidOut) height else measuredHeight + if (w > 0 && h > 0) { + maxAspectRatio = (w.toFloat() / h.toFloat()) + .coerceIn(MIN_ASPECT_RATIO, MAX_ASPECT_RATIO) + maxAspectRatioString = when { + maxAspectRatio <= MIN_ASPECT_RATIO -> MIN_ASPECT_RATIO_STRING + maxAspectRatio >= MAX_ASPECT_RATIO -> MAX_ASPECT_RATIO_STRING + else -> "$w:$h" + } + } + } + + /** + * Sets [preview]'s aspect ratio based on the preview image size. + * @return adjusted preview width + */ + private fun updatePreviewSize(preview: Preview, width: Int, height: Int): Int { val effectiveHeight = if (isLaidOut) height else measuredHeight - return if (bitmap.width <= 0 || bitmap.height <= 0) { + return if (width <= 0 || height <= 0) { + preview.aspectRatioString = "1:1" effectiveHeight } else { - val ar = (bitmap.width.toFloat() / bitmap.height.toFloat()) - .coerceIn(MIN_ASPECT_RATIO, MAX_ASPECT_RATIO) - (effectiveHeight * ar).roundToInt() + val aspectRatio = (width.toFloat() / height.toFloat()) + .coerceIn(MIN_ASPECT_RATIO, maxAspectRatio) + preview.aspectRatioString = when { + aspectRatio <= MIN_ASPECT_RATIO -> MIN_ASPECT_RATIO_STRING + aspectRatio >= maxAspectRatio -> maxAspectRatioString + else -> "$width:$height" + } + (effectiveHeight * aspectRatio).toInt() } } @@ -177,16 +214,6 @@ class ScrollableImagePreviewView : RecyclerView, ImagePreviewView { internal var aspectRatioString: String ) { constructor(type: PreviewType, uri: Uri) : this(type, uri, "1:1") - - internal fun updateAspectRatio(width: Int, height: Int) { - if (width <= 0 || height <= 0) return - val aspectRatio = width.toFloat() / height.toFloat() - aspectRatioString = when { - aspectRatio <= MIN_ASPECT_RATIO -> MIN_ASPECT_RATIO_STRING - aspectRatio >= MAX_ASPECT_RATIO -> MAX_ASPECT_RATIO_STRING - else -> "$width:$height" - } - } } enum class PreviewType { @@ -398,7 +425,7 @@ class ScrollableImagePreviewView : RecyclerView, ImagePreviewView { scope = null } - fun loadAspectRatios(maxWidth: Int, previewWidthCalculator: (Bitmap) -> Int) { + fun loadAspectRatios(maxWidth: Int, previewSizeUpdater: (Preview, Int, Int) -> Int) { val scope = this.scope ?: return val updates = ArrayDeque<Preview>(pendingPreviews.size) // replay 2 items to guarantee that we'd get at least one update @@ -440,10 +467,11 @@ class ScrollableImagePreviewView : RecyclerView, ImagePreviewView { // TODO: decide on adding a timeout imageLoader(preview.uri, isVisible) }.getOrNull() ?: continue - preview.updateAspectRatio(bitmap.width, bitmap.height) + val previewWidth = + previewSizeUpdater(preview, bitmap.width, bitmap.height) updates.add(preview) if (isVisible) { - loadedPreviewWidth += previewWidthCalculator(bitmap) + loadedPreviewWidth += previewWidth if (loadedPreviewWidth >= maxWidth) { // notify that the preview now can be displayed reportFlow.emit(updateEvent) |