dm-139
This commit is contained in:
parent
37d7eb6528
commit
025afc5b13
1 changed files with 44 additions and 7 deletions
|
|
@ -2,14 +2,22 @@ package com.example.login_v3.home.Message.UI.Detail.Message_Component
|
|||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.gestures.detectTransformGestures
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
|
|
@ -20,28 +28,57 @@ fun ImageLightbox(
|
|||
imageUrl: String,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
// 使用 Dialog 才能真正做到全螢幕蓋住 TopBar 與 BottomBar
|
||||
Dialog(
|
||||
onDismissRequest = onDismiss,
|
||||
properties = DialogProperties(
|
||||
usePlatformDefaultWidth = false // 關閉預設寬度限制,達到真正全螢幕
|
||||
usePlatformDefaultWidth = false
|
||||
)
|
||||
) {
|
||||
// 1. 宣告手勢狀態
|
||||
var scale by remember { mutableStateOf(1f) }
|
||||
var offset by remember { mutableStateOf(Offset.Zero) }
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color.Black.copy(alpha = 0.9f)) // 質感黑半透明背景
|
||||
.clickable { onDismiss() }, // 點擊背景任何地方都能關閉
|
||||
.background(Color.Black.copy(alpha = 0.9f))
|
||||
// 💡 如果圖片處於放大狀態,點擊背景不觸發關閉,方便使用者操作;縮回原大小時點擊背景才關閉
|
||||
.clickable(enabled = scale == 1f) { onDismiss() },
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
AsyncImage(
|
||||
model = imageUrl,
|
||||
contentDescription = "放大檢視圖片",
|
||||
contentScale = ContentScale.Fit, // 確保整張圖片能完整塞進螢幕
|
||||
contentScale = ContentScale.Fit,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.fillMaxHeight(0.85f) // 留一點上下操作空間
|
||||
.clickable(enabled = false) { } // 阻止點擊圖片本身時觸發關閉
|
||||
.fillMaxHeight(0.85f)
|
||||
// 2. 透過 graphicsLayer 將手勢狀態反映到畫面上
|
||||
.graphicsLayer(
|
||||
scaleX = scale,
|
||||
scaleY = scale,
|
||||
translationX = offset.x,
|
||||
translationY = offset.y
|
||||
)
|
||||
// 3. 監聽雙指與單指手勢
|
||||
.pointerInput(Unit) {
|
||||
detectTransformGestures { _, pan, zoom, _ ->
|
||||
// 計算新的縮放值,並限制在 1倍 到 4倍 之間
|
||||
val newScale = (scale * zoom).coerceIn(1f, 4f)
|
||||
|
||||
// 計算新的位移值(只有在放大狀態下才允許平移拖曳)
|
||||
val newOffset = if (newScale > 1f) {
|
||||
offset + pan
|
||||
} else {
|
||||
Offset.Zero // 縮回 1 倍時自動歸零
|
||||
}
|
||||
|
||||
scale = newScale
|
||||
offset = newOffset
|
||||
}
|
||||
}
|
||||
// 阻斷點擊圖片本身會關閉 Dialog 的行為
|
||||
.clickable(enabled = false) { }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue