summaryrefslogtreecommitdiff
path: root/java/src
diff options
context:
space:
mode:
author Andrey Epin <ayepin@google.com> 2023-04-13 18:45:10 -0700
committer Andrey Epin <ayepin@google.com> 2023-04-17 14:35:44 -0700
commit2783dd19f19bcbb523fa15e2d8154174f0978479 (patch)
tree9252a5b054c08589930e6678297920f17a3d2dfa /java/src
parent5c05904fbda5a7d8b0b3a1d474ab7224adb686ee (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.kt70
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)