From c65650cd8ccf28e8d69cb125173ea5d9ffe33758 Mon Sep 17 00:00:00 2001 From: cgspine Date: Wed, 16 Mar 2022 17:55:06 +0800 Subject: [PATCH] bugfix: transition issue. --- .../qmuiteam/photo/compose/GesturePhoto.kt | 33 ++++++++----- .../qmuidemo/fragment/lab/QDPhotoFragment.kt | 48 +++++++++++++++++-- 2 files changed, 65 insertions(+), 16 deletions(-) diff --git a/photo/src/main/java/com/qmuiteam/photo/compose/GesturePhoto.kt b/photo/src/main/java/com/qmuiteam/photo/compose/GesturePhoto.kt index 6447b8b2..eef47f1c 100644 --- a/photo/src/main/java/com/qmuiteam/photo/compose/GesturePhoto.kt +++ b/photo/src/main/java/com/qmuiteam/photo/compose/GesturePhoto.kt @@ -1,6 +1,5 @@ package com.qmuiteam.photo.compose -import android.util.Log import androidx.compose.animation.core.* import androidx.compose.foundation.background import androidx.compose.foundation.gestures.* @@ -41,7 +40,11 @@ fun QMUIGesturePhoto( shouldTransitionExit: Boolean = true, transitionTarget: Boolean = true, transitionDurationMs: Int = 360, - panEdgeProtection: Rect = Rect(0f, 0f, with(LocalDensity.current) { containerWidth.toPx() }, with(LocalDensity.current) { containerHeight.toPx() }), + panEdgeProtection: Rect = Rect( + 0f, + 0f, + with(LocalDensity.current) { containerWidth.toPx() }, + with(LocalDensity.current) { containerHeight.toPx() }), maxScale: Float = 4f, onPress: suspend PressGestureScope.(Offset) -> Unit = { }, onBeginPullExit: () -> Boolean, @@ -59,10 +62,10 @@ fun QMUIGesturePhoto( val density = LocalDensity.current val imagePaddingFix by remember(density, panEdgeProtection, isLongImage, containerWidth, containerHeight, calculatedImageRatio, imageRatio) { val (expectWidth, expectHeight) = calculateImageSize(containerWidth, containerHeight, calculatedImageRatio, isLongImage) - val widthPadding = with(density){ + val widthPadding = with(density) { (imageWidth - expectWidth).toPx() / 2 } - val heightPadding = with(density){ + val heightPadding = with(density) { (imageHeight - expectHeight).toPx() / 2 } @@ -70,8 +73,8 @@ fun QMUIGesturePhoto( } val usedImageRatioUpdater = remember { - val func: (Float)->Unit = { value -> - if(value > 0){ + val func: (Float) -> Unit = { value -> + if (value > 0) { calculatedImageRatio = value } } @@ -79,7 +82,6 @@ fun QMUIGesturePhoto( } - var backgroundTargetAlpha by remember { mutableStateOf(1f) } @@ -188,6 +190,7 @@ fun QMUIGesturePhoto( detectTapGestures( onTap = { if (shouldTransitionExit) { + reset() transitionTargetState = false } else { onTapExit(false) @@ -364,7 +367,7 @@ fun QMUIGesturePhoto( scale = photoTargetScale, translateX = photoTargetTranslateX, translateY = photoTargetTranslateY - ) { alpha, scale, translateX, translateY -> + ) { alpha, scale, translateX, translateY -> PhotoTransformContent( alpha, imageWidthPx, @@ -447,7 +450,7 @@ fun PhotoContentWithAlphaTransition( ) { if (it) 1f else 0f } - val duration = if(isGestureHandling) 0 else transitionDurationMs + val duration = if (isGestureHandling) 0 else transitionDurationMs val scaleState = animateFloatAsState( targetValue = scale, animationSpec = tween(durationMillis = duration) @@ -481,8 +484,14 @@ fun PhotoContentWithRectTransition( ) { if (it) Rect(translateX, translateY, translateX + imageWidth * scale, translateY + imageHeight * scale) else initRect } - val usedScale = rect.value.width / imageWidth - content(imageWidth, imageHeight, usedScale, rect.value.left, rect.value.top) + val isTransitionEnd = transition.currentState && transition.targetState + val usedWidth = if (isTransitionEnd) imageWidth else rect.value.width.coerceAtMost(imageWidth) + val usedHeight = if (isTransitionEnd) imageHeight else rect.value.height.coerceAtMost(imageHeight) + val usedScale = if (isTransitionEnd || rect.value.width > imageWidth) { + rect.value.width / imageWidth + } else 1f + content(usedWidth, usedHeight, usedScale, rect.value.left, rect.value.top) + } @Composable @@ -549,7 +558,7 @@ internal class GestureNestScrollConnection : NestedScrollConnection { private fun calculateImageSize(containerWidth: Dp, containerHeight: Dp, imageRatio: Float, isLongImage: Boolean): Pair { val layoutRatio = containerWidth / containerHeight return when { - isLongImage || imageRatio <= 0f -> containerWidth to containerHeight + isLongImage || imageRatio <= 0f -> containerWidth to containerHeight imageRatio >= layoutRatio -> containerWidth to (containerWidth / imageRatio) else -> (containerHeight * imageRatio) to containerHeight } diff --git a/qmuidemo/src/main/java/com/qmuiteam/qmuidemo/fragment/lab/QDPhotoFragment.kt b/qmuidemo/src/main/java/com/qmuiteam/qmuidemo/fragment/lab/QDPhotoFragment.kt index 02420df1..50d3281c 100644 --- a/qmuidemo/src/main/java/com/qmuiteam/qmuidemo/fragment/lab/QDPhotoFragment.kt +++ b/qmuidemo/src/main/java/com/qmuiteam/qmuidemo/fragment/lab/QDPhotoFragment.kt @@ -1,22 +1,25 @@ package com.qmuiteam.qmuidemo.fragment.lab +import android.graphics.Bitmap +import android.graphics.BitmapFactory import android.util.Log import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.registerForActivityResult +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember +import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.graphics.painter.BitmapPainter import androidx.compose.ui.unit.dp import androidx.core.net.toUri +import androidx.lifecycle.lifecycleScope import com.qmuiteam.compose.core.ui.QMUITopBarBackIconItem import com.qmuiteam.compose.core.ui.QMUITopBarTextItem import com.qmuiteam.compose.core.ui.QMUITopBarWithLazyScrollState @@ -26,11 +29,15 @@ import com.qmuiteam.photo.activity.getQMUIPhotoPickResult import com.qmuiteam.photo.coil.QMUICoilPhotoProvider import com.qmuiteam.photo.coil.QMUIMediaCoilPhotoProviderFactory import com.qmuiteam.photo.compose.QMUIPhotoThumbnailWithViewer +import com.qmuiteam.photo.util.QMUIPhotoHelper import com.qmuiteam.qmui.arch.annotation.LatestVisitRecord import com.qmuiteam.qmuidemo.R import com.qmuiteam.qmuidemo.base.ComposeBaseFragment import com.qmuiteam.qmuidemo.lib.annotation.Widget +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext @Widget(name = "QMUI Photo", iconRes = R.mipmap.icon_grid_in_progress) @LatestVisitRecord @@ -65,6 +72,7 @@ class QDPhotoFragment : ComposeBaseFragment() { QMUIPhotoPickerActivity::class.java, QMUIMediaCoilPhotoProviderFactory::class.java )) + } ) ) @@ -81,6 +89,10 @@ class QDPhotoFragment : ComposeBaseFragment() { PickerResult() } +// item { +// TestImageCompress() +// } + item { Box( modifier = Modifier @@ -334,4 +346,32 @@ class QDPhotoFragment : ComposeBaseFragment() { } + + @Composable + fun TestImageCompress(){ + var bitmap by remember { + mutableStateOf(null) + } + LaunchedEffect(""){ + lifecycleScope.launch { + withContext(Dispatchers.IO){ + QMUIPhotoHelper.compressByShortEdgeWidthAndByteSize( + requireContext(), + { + it.assets.open("test.png") + }, + 500 + )?.inputStream().use { + if(it != null){ + bitmap = BitmapFactory.decodeStream(it) + } + } + } + } + } + + if(bitmap != null){ + Image(painter = BitmapPainter(bitmap!!.asImageBitmap()), contentDescription = "") + } + } } \ No newline at end of file