Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
Tags
- scss
- 자바스크립트
- java 출력
- abap
- develop
- ListView
- Flutter
- java
- println
- npm
- 자바 포맷 출력
- java 콘솔 출력 차이
- DART
- lifecycle
- Clean Architecture
- 자바 출력 방식
- 앱심사
- JQ
- firebase
- printf
- LLM
- JS
- UI/UX
- nodejs
- 배포
- 단축키
- 엡
- unity
- riverpod
- react
Archives
- Today
- Total
guricode
[flutter]자취의 정석 -6 댓글 꾹~ 눌렀을때 메뉴 펼치기(신고하기,차단하기 등등) 본문
댓글 꾹 누른 위치에 팝업 띄우는 법 요약
onLongPressStart의 details.globalPosition으로 터치 좌표 확보
onLongPressStart: (details)의 details은onLongPressStart한 정보를 담고 있다.
onLongPressStart: (details) {
print(details.globalPosition); // 화면 전체 기준 좌표 (Offset)
print(details.localPosition); // 해당 위젯 기준 좌표 (Offset)
print(details.kind); // 입력 종류 (터치, 마우스 등) PointerDeviceKind
}
일단 기능은 넣지 않았지만 메뉴가 나오게끔 작업을 미리 해뒀다
아이콘은
https://fonts.google.com/icons?icon.query=share
GestureDetector(
onLongPressStart: (details) async {
//details = onLongPressStart했을떄 정보
//현재화면의 최상단 레이어(Overlay)를 찾고 그 랜더박스 정보 제공, 목적: 화면전체 크기를 얻어 메뉴 위치계산에 사용
final overlay =
Overlay.of(context).context.findRenderObject() as RenderBox;
//showMenu : 팝업 메뉴 표시
final selected = await showMenu<String>(
//꾹 눌렀을때 나오는 메뉴 모양 커스텀
shape: RoundedRectangleBorder(
borderRadius: BorderRadiusGeometry.circular(15),
),
context: context,
//작은사각형이 큰 사각형의 어디있는지 상대좌표로 변환하여 메뉴 시작위치가 터치 지점으로 잡힘
position: RelativeRect.fromRect(
//사용자가 누른 지점을 0,0사이즈의 사각형으로 표현
Rect.fromLTWH(
details.globalPosition.dx,
details.globalPosition.dy,
0,
0,
),
//화면 전체를 덮는 사각형
Offset.zero & overlay.size,
),
color: Colors.white,
items: [
PopupMenuItem(
value: 'report',
child: Row(
children: [
Text('신고하기'),
SizedBox(
width: 50,
),
Spacer(),
Icon(Icons.notifications_none),
],
),
),
PopupMenuItem(
value: 'block',
child: Row(
children: [
Text('차단하기'),
Spacer(),
Icon(Icons.do_not_disturb_on_outlined),
],
),
),
PopupMenuItem(
value: 'share',
child: Row(
children: [
Text('공유하기'),
Spacer(),
Icon(Icons.share),
],
),
),
],
);
//selected의 value에 따라 기능실행
switch (selected) {
case 'report':
// 신고 처리
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('신고 완료')));
break;
case 'block':
// 차단 처리
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('차단 완료')));
break;
case 'share':
// 공유 처리
// Share.share('공유할 내용'); // share_plus 사용 시
break;
case null:
// 메뉴 밖을 눌러 닫힘. 아무것도 하지 않음.
break;
}
;
},
1. Overlay.of(context)
- context 로부터 가장 가까운 Overlay 위젯을 찾는다.
- 반환 타입: OverlayState?
→ 여기서 ?.context 하면 OverlayState 가 들고 있는 자신의 BuildContext를 얻는다.
즉,
final overlay = Overlay.of(context); // OverlayState
final overlayContext = overlay.context; // Overlay의 BuildContext
context.findRenderObject()
- BuildContext 로부터 실제 RenderObject를 가져온다.
- RenderObject는 화면에 실제로 그려지는 객체. 레이아웃/페인트 계산을 담당.
- UI 위치 계산할 때 꼭 필요하다.
as RenderBox
- RenderObject 는 추상 클래스.
- 대부분의 위젯(특히 박스 기반)은 실제로 RenderBox를 쓴다.
- 그래서 위치·크기 계산할 때는 RenderBox로 캐스팅해야 한다.
final overlay = Overlay.of(context).context.findRenderObject() as RenderBox;
- Overlay.of(context) → OverlayState 찾기
- .context → 그 Overlay의 BuildContext
- .findRenderObject() → 실제 RenderObject 꺼내기
- as RenderBox → 좌표·사이즈 계산 가능한 RenderBox로 캐스팅
팝업 메뉴나 다이얼로그 같은 걸 띄울 때,
화면 전체 기준 좌표(globalPosition)와 Overlay의 크기(overlay.size)가 필요하다.
RelativeRect.fromRect(
Rect.fromLTWH(details.globalPosition.dx, details.globalPosition.dy, 0, 0),
Offset.zero & overlay.size, // overlay 전체 크기
)
RelativeRect.fromRect 는 작은 직사각형(Rect)을 큰 직사각형(Rect) 안에서 상대적 위치로 바꿔주는 도우미다.
RelativeRect.fromRect(
Rect rect, // 기준이 되는 작은 사각형 (ex. 메뉴 뜰 위치)
Rect container, // 전체 컨테이너 (ex. Overlay 전체 화면 크기)
)
'앱 > Flutter&Dart' 카테고리의 다른 글
| [flutter]자취의 정석 -8 게시글, 댓글 페이지네이션 microtask (0) | 2025.10.02 |
|---|---|
| [flutter]자취의 정석 -7 커뮤니티 목록 안 뜸 / ref dispose 오류 (0) | 2025.09.29 |
| [flutter]자취의 정석 -5 NestedScrollView를 이용한 스크롤 화면 (0) | 2025.09.20 |
| [flutter]자취의 정석 -4,bottomSheet에 TextFormField 입력시 hassized문제 (0) | 2025.09.19 |
| [flutter]자취의 정석 -3 : TabBar를 사용한 카테고리 선택 구현 (0) | 2025.09.16 |