У меня есть GlideImage внутри коробки. Внутри этой коробки также есть кнопка со значком. Я хочу, чтобы при нажатии на кнопку изображение максимизировалось и занимало весь экран с кнопкой в правом нижнем углу, где можно его свернуть. Я также хотел бы увеличить его. Кто-нибудь знает, как я могу это сделать и возможно ли это в текущем состоянии Jetpack Compose?
Я оставляю вам код, который мне нужен для создания коробки с изображением и значком.
Заранее благодарю за любую помощь.
@ExperimentalGlideComposeApi
@Composable
fun BuildImage(imageUrl: String) {
Box(
modifier = Modifier
.padding(vertical = 25.dp, horizontal = 25.dp)
.background(
brush = Brush.linearGradient(
listOf(
Color.Gray,
Color.White
)
),
shape = RoundedCornerShape(14.dp)
)
.clip(RoundedCornerShape(14.dp))
) {
GlideImage(
model = imageUrl,
contentDescription = null,
contentScale = ContentScale.FillBounds
)
Box(modifier = Modifier.matchParentSize(), contentAlignment = Alignment.BottomEnd) {
IconButton(
onClick = { /* TO IMPLEMENT */ },
modifier = Modifier
.padding(11.dp)
.background(Color.Blue, RoundedCornerShape(3.dp))
.clip(RoundedCornerShape(3.dp))
.size(52.dp)
) {
Icon(
painter = painterResource(id = R.drawable.maximize),
contentDescription = null,
tint = Color.Unspecified
)
}
}
}
}
@ADM Я не могу импортировать масштабируемое расширение из модификатора, также не могу импортировать DragObserver. Я что-то упускаю?
Вы можете сделать это следующим образом:
@OptIn(ExperimentalGlideComposeApi::class)
@Composable
fun Q74501531() {
val configuration = LocalConfiguration.current
val screenWidth = configuration.screenWidthDp.dp // Get screen width as dp from local configuration
val screenHeight = configuration.screenHeight.dp // You can also get screen height but for demo it's unused
Column(
modifier = Modifier.fillMaxSize()
) {
var isExpanded by remember { mutableStateOf(false) } // Trigger state for change width and height
val width by animateDpAsState(if (isExpanded) screenWidth else screenWidth / 3)
val height by animateDpAsState(if (isExpanded) screenWidth / 2 else screenWidth / 5)
GlideImage(
modifier = Modifier.size(width, height),
model = "https://upload.wikimedia.org/wikipedia/commons/9/9a/Gull_portrait_ca_usa.jpg",
contentDescription = null,
contentScale = ContentScale.Crop
)
Spacer(Modifier.weight(1f))
TextButton(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp),
onClick = { isExpanded = !isExpanded }
) {
Text("Toggle")
}
}
}
Демо: https://thewikihow.com/video_PwPagLi8nEs
В моем случае использования я использовал предложение @ADM для решения моей проблемы. Когда я нажимал на кнопку, открывался диалог, который занимал весь экран, а внутри него показывалось нужное мне изображение с помощью Glide. Чтобы увеличить изображение, я использовал метод ZoomableImage, который вы можете увидеть ниже.
Dialog(
properties = DialogProperties(usePlatformDefaultWidth = false),
onDismissRequest = { /* implement */ }
) {
Box(modifier = Modifier.fillMaxSize()) {
ZoomableImage(imageUrl)
}
}
@ExperimentalGlideComposeApi
@Composable
fun ZoomableImage(model: Any, contentDescription: String? = null) {
val angle by remember { mutableStateOf(0f) }
var zoom by remember { mutableStateOf(1f) }
var offsetX by remember { mutableStateOf(0f) }
var offsetY by remember { mutableStateOf(0f) }
val configuration = LocalConfiguration.current
val screenWidth = configuration.screenWidthDp.dp.value
val screenHeight = configuration.screenHeightDp.dp.value
GlideImage(
model,
contentDescription = contentDescription,
contentScale = ContentScale.Fit,
modifier = Modifier
.offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
.graphicsLayer(
scaleX = zoom,
scaleY = zoom,
rotationZ = angle
)
.pointerInput(Unit) {
detectTransformGestures(
onGesture = { _, pan, gestureZoom, _ ->
zoom = (zoom * gestureZoom).coerceIn(1F..4F)
if (zoom > 1) {
val x = (pan.x * zoom)
val y = (pan.y * zoom)
val angleRad = angle * PI / 180.0
offsetX =
(offsetX + (x * cos(angleRad) - y * sin(angleRad)).toFloat()).coerceIn(
-(screenWidth * zoom)..(screenWidth * zoom)
)
offsetY =
(offsetY + (x * sin(angleRad) + y * cos(angleRad)).toFloat()).coerceIn(
-(screenHeight * zoom)..(screenHeight * zoom)
)
} else {
offsetX = 0F
offsetY = 0F
}
}
)
}
.fillMaxSize()
)
}
Создайте новый Composable с полноэкранным изображением и откройте его при максимальном нажатии. Это также может быть полноэкранный диалог. Чтобы увеличить масштаб, вы можете попробовать что-то вроде этого или вы можете использовать любую старую библиотеку xml с AndroidView в компоновке.