From b461bfffbab48b8c3b03ff50f775c4b9d8b4debc Mon Sep 17 00:00:00 2001 From: jjangddu Date: Wed, 17 Jun 2026 16:54:11 +0900 Subject: [PATCH] =?UTF-8?q?ux:=20Sensor=20Alignment=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=95=84=EC=9B=83=20=EC=A0=95=ED=98=95=ED=99=94=20=E2=80=94=20?= =?UTF-8?q?=EB=B0=95=EC=8A=A4=20=ED=95=AD=EC=83=81=20=EC=9E=90=EB=A6=AC,?= =?UTF-8?q?=20weight=205=EB=93=B1=EB=B6=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 요구사항 (사용자 정의 순서): Title / spacer / Hint1 / spacer / Illustration / spacer / Step / spacer / Hint2 / spacer / Start / Skip 변경: 1) Hint 1 박스: if(waitingForStart) 외부 가드 제거 → 박스는 항상 렌더. 텍스트만 waitingForStart 시 표시. heightIn min 96dp (현재 자연 높이 ~64dp 의 1.5배). 2) Hint 2 박스: 동일 패턴 — 박스 항상 렌더, 텍스트는 hint2Visible 시만, heightIn min 102dp (28sp 텍스트 기준 1.5배). 3) Step ↔ Hint 2 간격: Spacer 8dp → weight 1f (5번째 분할). 4) Skip ↔ 하단: weight 1f → 고정 16dp (사용자 요구 — Skip 이 화면 아래 가깝게). 결과: 빈 공간이 5개 위치 (Title↔Hint1, Hint1↔Illustration, Illustration↔Step, Step↔Hint2, Hint2↔Button) 에 균등 분배. 내용 없을 때도 Hint 박스 자리는 그대로 유지 (배경/높이). Co-Authored-By: Claude Opus 4.7 --- .../ui/views/monitoring/PlacementGuideView.kt | 75 ++++++++++--------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PlacementGuideView.kt b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PlacementGuideView.kt index d5a2bad..5b44941 100644 --- a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PlacementGuideView.kt +++ b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PlacementGuideView.kt @@ -237,30 +237,31 @@ fun PlacementGuideView(appState: AppState) { // Title(top bar) ↔ Hint 1 사이 — 첫 weight spacer (위쪽 빈 공간 균등 분배). Spacer(modifier = Modifier.weight(1f)) - // ─── (1) Hint 1 — waitingForStart 일 때만 렌더 (빈 칸 자체 숨김) ─── - if (waitingForStart) { - val hint1Bg = Color(0xFFFFF3E0) - val hint1Text = remember { - buildAnnotatedString { - val full = "Place VesiScan above the pubic bone, then press Start" - val key = "pubic bone" - val idx = full.indexOf(key, ignoreCase = true) - if (idx >= 0) { - append(full.substring(0, idx)) - withStyle(SpanStyle(color = Color.Red, fontWeight = FontWeight.ExtraBold)) { - append(full.substring(idx, idx + key.length)) - } - append(full.substring(idx + key.length)) - } else append(full) - } + // ─── (1) Hint 1 — 박스는 항상 자리(높이 1.5×), 텍스트는 waitingForStart 시만 ─── + val hint1Bg = Color(0xFFFFF3E0) + val hint1Text = remember { + buildAnnotatedString { + val full = "Place VesiScan above the pubic bone, then press Start" + val key = "pubic bone" + val idx = full.indexOf(key, ignoreCase = true) + if (idx >= 0) { + append(full.substring(0, idx)) + withStyle(SpanStyle(color = Color.Red, fontWeight = FontWeight.ExtraBold)) { + append(full.substring(idx, idx + key.length)) + } + append(full.substring(idx + key.length)) + } else append(full) } - Box( - modifier = Modifier - .fillMaxWidth() - .background(hint1Bg.copy(alpha = 0.7f), RoundedCornerShape(16.dp)) - .padding(horizontal = 20.dp, vertical = 14.dp), - contentAlignment = Alignment.Center // 상하 중앙 정렬 - ) { + } + Box( + modifier = Modifier + .fillMaxWidth() + .heightIn(min = 96.dp) // 1.5× of current ~64dp natural height + .background(hint1Bg.copy(alpha = 0.7f), RoundedCornerShape(16.dp)) + .padding(horizontal = 20.dp, vertical = 14.dp), + contentAlignment = Alignment.Center + ) { + if (waitingForStart) { Text( text = hint1Text, fontSize = 26.sp, @@ -269,7 +270,6 @@ fun PlacementGuideView(appState: AppState) { textAlign = TextAlign.Center, ) } - Spacer(modifier = Modifier.height(8.dp)) } // 타이틀은 top bar 로 이동 (← 옆 절대 가운데) — 본문 중복 제거. @@ -532,18 +532,20 @@ fun PlacementGuideView(appState: AppState) { } } - Spacer(modifier = Modifier.height(8.dp)) + // Step ↔ Hint 2 사이 — weight spacer + Spacer(modifier = Modifier.weight(1f)) - // ─── (5) Hint 2 — 측정 중 방향 안내 (waitingForStart 또는 빈 텍스트면 칸 자체 숨김) ─── + // ─── (5) Hint 2 — 박스는 항상 자리(높이 1.5×), 텍스트는 가시 조건일 때만 ─── val hint2Visible = !waitingForStart && displayHint.text.isNotBlank() - if (hint2Visible) { - Box( - modifier = Modifier - .fillMaxWidth() - .background(hintBg.copy(alpha = 0.7f), RoundedCornerShape(16.dp)) - .padding(horizontal = 20.dp, vertical = 14.dp), - contentAlignment = Alignment.Center - ) { + Box( + modifier = Modifier + .fillMaxWidth() + .heightIn(min = 102.dp) // 1.5× of current ~68dp natural height + .background(hintBg.copy(alpha = 0.7f), RoundedCornerShape(16.dp)) + .padding(horizontal = 20.dp, vertical = 14.dp), + contentAlignment = Alignment.Center + ) { + if (hint2Visible) { Text( text = displayHint, fontSize = 28.sp, @@ -552,7 +554,6 @@ fun PlacementGuideView(appState: AppState) { textAlign = TextAlign.Center, ) } - Spacer(modifier = Modifier.height(8.dp)) } // 채널 dot row (개발자 모드에서만 표시) @@ -1091,8 +1092,8 @@ fun PlacementGuideView(appState: AppState) { ) } - // 하단 weight spacer — Skip 아래 빈 공간 (세 번째 분할). - Spacer(modifier = Modifier.weight(1f)) + // 하단 작은 padding 만 (Skip 이 화면 아래 가까이 오도록). + Spacer(modifier = Modifier.height(16.dp)) } // end scrollable Column // Floating settings overlay (개발자 모드)