Как увеличить изображение при нажатии кнопки в джетпаке?

У меня есть 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
                )
            }
        }
    }
}

Создайте новый Composable с полноэкранным изображением и откройте его при максимальном нажатии. Это также может быть полноэкранный диалог. Чтобы увеличить масштаб, вы можете попробовать что-то вроде этого или вы можете использовать любую старую библиотеку xml с AndroidView в компоновке.

ADM 19.11.2022 17:05

@ADM Я не могу импортировать масштабируемое расширение из модификатора, также не могу импортировать DragObserver. Я что-то упускаю?

R0ck 21.11.2022 15:12
Как настроить Tailwind CSS с React.js и Next.js?
Как настроить Tailwind CSS с React.js и Next.js?
Tailwind CSS - единственный фреймворк, который, как я убедился, масштабируется в больших командах. Он легко настраивается, адаптируется к любому...
LeetCode запись решения 2536. Увеличение подматриц на единицу
LeetCode запись решения 2536. Увеличение подматриц на единицу
Увеличение подматриц на единицу - LeetCode
Переключение светлых/темных тем
Переключение светлых/темных тем
В Microsoft Training - Guided Project - Build a simple website with web pages, CSS files and JavaScript files, мы объясняем, как CSS можно...
Отношения "многие ко многим" в Laravel с методами присоединения и отсоединения
Отношения "многие ко многим" в Laravel с методами присоединения и отсоединения
Отношения "многие ко многим" в Laravel могут быть немного сложными, но с помощью Eloquent ORM и его моделей мы можем сделать это с легкостью. В этой...
В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Карта дорог Беладжар PHP Laravel
Карта дорог Беладжар PHP Laravel
Laravel - это PHP-фреймворк, разработанный для облегчения разработки веб-приложений. Laravel предоставляет различные функции, упрощающие разработку...
1
2
126
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете сделать это следующим образом:

@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()
    )
}

Другие вопросы по теме