Skip to content

fix(map): 시설 상세를 스냅샷-스왑 바텀시트로(백지/오버플로 해결)#29

Merged
seizeh merged 3 commits into
mainfrom
fix/facility-detail-bottomsheet
Jun 29, 2026
Merged

fix(map): 시설 상세를 스냅샷-스왑 바텀시트로(백지/오버플로 해결)#29
seizeh merged 3 commits into
mainfrom
fix/facility-detail-bottomsheet

Conversation

@seizeh

@seizeh seizeh commented Jun 29, 2026

Copy link
Copy Markdown
Owner

문제

지도 마커 탭 → 시설 상세 본문이 백지가 되던 버그(#28). 후기 기능 추가 중 발생.

원인 (정정)

처음엔 네이버 지도 PlatformView 합성 버그로 의심했으나 틀렸음. 진짜 원인은
지도 탭 위젯 트리 컨텍스트에서 본문이 받는 너비가 tight-infinity 로 손상되어,
머티리얼 버튼/Spacer/ExpandedBoxConstraints forces an infinite width
레이아웃 실패한 것. Container/Text 같은 intrinsic 위젯만 살아남았음.

해결

  • lib/widgets/map_bottom_sheet.dart (신규): 라이브 지도를 controller.takeSnapshot()
    으로 얼린 뒤 스냅샷 이미지 위에 커스텀 바텀시트(스크림+드래그닫기+슬라이드)를 올림
    → PlatformView 가 시트 밑에 없어 충돌 회피. 지도는 뒤에 보임(원래 의도한 UX).
  • facility_sheet.dart: FacilityDetailScreenFacilityDetailContent.
    머티리얼 버튼 → GestureDetector+Container 탭, 폭은 시트의 Align>SizedBox 가 고정.
    긴 주소는 Expanded(폭 유한)로 줄바꿈(error2.png 노란 오버플로 해결).
  • map_tab.dart: showSheetOverMap/탭내 스왑, AutomaticKeepAlive,
    _lastCamera 로 지도 카메라 복원, PopScope 안드로이드 뒤로가기 닫기.
  • facility_review_screen.dart: 무한제약 핵 제거(후기 작성은 일반 라우트라 안전).

검증

  • flutter analyze 무이슈, flutter test 통과.
  • 실기기(emulator-5554): 마커 탭 → 상세 풀 렌더, overflow=0 / exception=0.
  • 뒤로 → 지도 복원. 클러스터 탭 → 게시글 목록 정상.

트레이드오프

시트 열고닫을 때마다 지도 dispose→recreate(타일·마커 재로딩 ~1–2s). _lastCamera
위치 점프는 방지.

Refs #28

🤖 Generated with Claude Code

seizeh and others added 2 commits June 29, 2026 22:45
지도 마커 탭 시 시설 상세 본문이 백지가 되던 버그(#28) 해결. 원인은
PlatformView가 아니라, 지도 탭 위젯 트리 컨텍스트에서 본문이 받는 너비가
tight-infinity 로 손상되어 머티리얼 버튼/Spacer/Expanded 가
"BoxConstraints forces an infinite width" 로 레이아웃 실패한 것.

- map_bottom_sheet.dart 신규: 라이브 지도를 takeSnapshot() 으로 얼린 뒤
  그 위에 커스텀 바텀시트(스크림+드래그닫기+슬라이드)를 올리는 방식.
  PlatformView 가 시트 밑에 없어 합성/hit-test 충돌 회피.
- facility_sheet.dart: FacilityDetailScreen → FacilityDetailContent.
  머티리얼 버튼을 GestureDetector+Container 탭으로, 본문 폭은 시트의
  Align>SizedBox 가 고정. 긴 주소는 Expanded(폭 유한)로 줄바꿈(error2.png).
- map_tab.dart: showSheetOverMap/탭내 스왑, AutomaticKeepAlive,
  _lastCamera 로 지도 복원, PopScope 뒤로가기 닫기.
- facility_review_screen.dart: 무한제약 핵 제거(라우트라 안전).
- test: FacilityDetailContent + MapBottomSheet 스모크 테스트.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
클러스터 탭 시 전용화면(_RegionPostsScreen) 풀스크린 스왑 대신, 시설 상세와
동일한 showSheetOverMap 바텀시트로 통일(지도가 뒤에 보임). 목록은 한 화면에
여러 개라 PostCard 카드 대신 컴팩트 행으로: 사진은 56px 작은 썸네일로 축소,
통계는 하트/댓글만 간소 표시.

- region_posts_sheet.dart 신규(RegionPostsContent): 컴팩트 행 + 56px 썸네일.
  게시글 탭 → PostDetailScreen 라우트 push(시트 밑엔 PlatformView 없어 안전).
- map_tab.dart: _showRegionPosts → showSheetOverMap(.., heightFactor: 0.7).
  _detailCluster state/_RegionPostsScreen 제거. showSheetOverMap 에 heightFactor.
- map_bottom_sheet.dart: 스냅샷-스왑이라 본문은 평범한 위젯 트리 →
  Expanded/Spacer/머티리얼 안전(과거 "금지" 주석 정정).
- test: RegionPostsContent 스모크 테스트.

실기기 검증(복정동 3개 클러스터): 바텀시트 렌더 → 게시글 탭 → 상세 →
뒤로 시트 복귀 → 스크림 닫기 → 지도 카메라 복원. overflow=0, exception=0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@seizeh

seizeh commented Jun 29, 2026

Copy link
Copy Markdown
Owner Author

추가 커밋: 동네 게시글도 바텀시트로 통일 (42aecce)

리뷰 중 "게시글은 왜 바텀시트가 아니냐"는 지적을 반영해, 동네 클러스터 게시글 목록도
전용화면 풀스크린 스왑(_RegionPostsScreen) 대신 시설 상세와 동일한 showSheetOverMap
바텀시트
로 통일했습니다(지도가 뒤에 보임).

  • 목록은 한 화면에 여러 개라 PostCard 카드 대신 컴팩트 행: 사진은 56px 작은 썸네일로
    축소, 통계는 하트/댓글만 간소 표시.
  • RegionPostsContent(신규), showSheetOverMapheightFactor 추가(게시글은 0.7).
  • 스냅샷-스왑이라 시트 밑엔 PlatformView 가 없어 본문은 평범한 위젯 트리 → Expanded/Spacer/
    머티리얼 안전(map_bottom_sheet 주석 정정).

실기기 검증(복정동 3개 클러스터): 바텀시트 렌더 → 게시글 탭 → 상세 → 뒤로 시트 복귀 →
스크림 닫기 → 지도 카메라 복원. overflow=0, exception=0.

게시글이 많아질 때를 대비한 "더보기 → 커뮤니티(우리동네 필터 토글)" 흐름은 향후 옵션으로
#30 에 분리해 두었습니다(이번 범위 밖).

기존엔 시트가 열리면 build() 가 다른 Scaffold(스냅샷+시트)를 리턴해 NaverMap 이
트리에서 빠졌고, 닫을 때 PlatformView 가 recreate 되며 타일·마커가 재로딩됐다
(닫을 때 거슬리는 재렌더의 원인).

실기기 검증 결과 "라이브 PlatformView 위 모달은 합성 충돌로 깨진다"는 가설은
틀렸음 — Flutter 오버레이는 라이브 네이버 지도(SurfaceProducer/Impeller) 위에
정상 합성된다. 따라서:
- build() 가 시트 열려도 같은 Scaffold/NaverMap 을 유지하고 MapBottomSheet 만
  오버레이로 얹는다(시트 열리면 검색/칩/내위치는 if(!sheetOpen) 로 숨김).
- 스냅샷 기계장치 제거: takeSnapshot / _mapSnapshot / Image.file / dart:io.
  스크림이 라이브 지도를 어둡게 덮어 동일한 바텀시트 룩 유지.

→ 닫아도 지도 dispose/recreate 없음(재로딩 사라짐). 검증: 닫을 때 로그에 지도
재초기화 마커(TextureView/GPU/ParseStyle) 0건. 시설·게시글 시트 둘 다
라이브 지도 위 렌더 정상, overflow=0, exception=0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@seizeh

seizeh commented Jun 29, 2026

Copy link
Copy Markdown
Owner Author

추가 커밋: 닫을 때 지도 재생성 제거 (13d2b63)

"상세를 닫으면 지도가 recreate 되어 재렌더가 거슬린다"는 지적 반영.

원인: 시트가 열리면 build() 가 스냅샷+시트의 다른 Scaffold 를 리턴 → NaverMap 이 트리에서
빠짐 → 닫을 때 PlatformView가 recreate(타일·마커 재로딩).

확인된 사실: 실기기 검증 결과 "라이브 PlatformView 위 모달은 합성 충돌로 깨진다"는 가설은 틀렸음.
Flutter 오버레이는 라이브 네이버 지도(SurfaceProducer/Impeller) 위에 정상 합성됩니다(스냅샷이 라이브
지도를 멀쩡히 덮은 것으로 z-order 확인). 즉 스냅샷도, 지도 제거도 불필요.

변경:

  • build() 가 시트가 열려도 같은 Scaffold/NaverMap 유지, MapBottomSheet 만 오버레이로 얹음
    (시트 열리면 검색/칩/내위치는 if (!sheetOpen) 로 숨김).
  • 스냅샷 기계장치 전부 제거(takeSnapshot/_mapSnapshot/Image.file/dart:io). 스크림이 라이브
    지도를 어둡게 덮어 동일한 룩 유지.

검증(복정동, 실기기): 게시글·시설 시트 모두 라이브 지도 위에 직접 렌더 정상 → 닫으면 지도 즉시
복귀, 재로딩 없음. 닫을 때 로그의 지도 재초기화 마커(Installing custom TextureView/GPU Identifier/
ParseStyle) 0건. overflow=0, exception=0. flutter analyze/flutter test 통과.

부수 효과: 여는 속도도 빨라짐(스냅샷 캡처 단계 제거).

@seizeh
seizeh merged commit 31f20ce into main Jun 29, 2026
@seizeh
seizeh deleted the fix/facility-detail-bottomsheet branch June 29, 2026 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant