본문 바로가기
전체보기

[TIL-4] PopupMenuButton, bottomsheet Flutter 중고마켓 앱 정리

by 오늘도잡학다식 2025. 4. 15.

 

📱 Flutter 중고마켓 앱 TIL 정리

1. MyTab UI 구현

  • 사용자 프로필 박스를 Row로 구성하고, 우측에 버튼 배치
  • 각 항목을 GestureDetector로 감싸고, SnackBar로 피드백 처리

Row(
  children: [
    UserProfileImage(dimension: 50, imgSrc: 'https://...'),
    SizedBox(width: 10),
    Expanded(child: Text('오상구님')),
    GestureDetector(
      onTap: () {}, // 프로필수정
      child: Container(
        padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
        color: Colors.grey,
        child: Text('프로필수정', style: TextStyle(color: Colors.white)),
      ),
    )
  ],
)

---

2. ProductDetailPage UI 구성

  • PageView.builder로 이미지 넘기기 구현
  • Scaffold.bottomSheet에 고정 영역 추가
  • 하단 영역은 bottomPadding을 포함시켜야 SafeArea 침범 방지

// 이미지 넘기기
SizedBox(
  height: 500,
  child: PageView.builder(
    itemCount: 3,
    itemBuilder: (context, index) => Image.network('https://picsum.photos/200/300'),
  ),
);

// bottomSheet 구성
bottomSheet: ProductDetailBottomSheet(
  bottomPadding: MediaQuery.of(context).padding.bottom,
)

---

3. ProductWritePage 구성

  • PopupMenuButton으로 카테고리 선택 구현
  • TextFormField에 유효성 검사 함수 연결

// 카테고리 선택
PopupMenuButton(
  onSelected: (value) => print(value),
  itemBuilder: (_) => [
    PopupMenuItem(value: '디지털', child: Text('디지털')),
    PopupMenuItem(value: '생활', child: Text('생활')),
  ],
  child: Text('카테고리 선택'),
)

// 유효성 검사 예시
TextFormField(
  controller: titleController,
  validator: ValidatorUtils.validatorTitle,
  decoration: InputDecoration(hintText: "상품명을 입력해주세요"),
)

---

4. ChatDetailPage UI

  • ListView.separated를 사용하여 채팅 간격 조절
  • 보낸 메시지와 받은 메시지를 각각 다른 위젯으로 관리

// 받은 메시지
Row(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    showProfile ? UserProfileImage(imgSrc: imgUrl, dimension: 50) : SizedBox(width: 50),
    SizedBox(width: 8),
    Expanded(
      child: Container(
        padding: EdgeInsets.all(8),
        decoration: BoxDecoration(
          color: Colors.grey[200],
          borderRadius: BorderRadius.circular(16),
        ),
        child: Text(content),
      ),
    ),
  ],
)

// 보낸 메시지
Row(
  mainAxisAlignment: MainAxisAlignment.end,
  children: [
    Container(
      padding: EdgeInsets.all(8),
      decoration: BoxDecoration(
        color: Colors.grey[300],
        borderRadius: BorderRadius.circular(16),
      ),
      child: Text(content),
    ),
  ],
)

---

✅ 오늘의 학습 요약

  • bottomSheet는 항상 SafeArea 고려해야 함 (MediaQuery.of(context).padding.bottom)
  • PopupMenuButton은 UI 선택 시 깔끔하게 쓰일 수 있음
  • TextFormField + validator 조합으로 손쉬운 유효성 검사 구현 가능
  • UI 파일을 기능별로 분리해서 구조 잡기 연습 완료