From 223ab041d67dce147fb728ad3d79edd3ab019ef5 Mon Sep 17 00:00:00 2001 From: ormee Date: Mon, 18 May 2026 12:50:24 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat(wedu):=20=EC=B0=B8=EC=97=AC=20?= =?UTF-8?q?=EC=A4=91=EC=9D=B8=20=EA=B0=99=EC=9D=B4=EB=B0=A9=20=EC=98=81?= =?UTF-8?q?=EC=97=AD=20=EC=A0=91=EA=B8=B0/=ED=8E=BC=EC=B9=98=EA=B8=B0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 리스트 아래 스크롤 시 참여 중인 같이방 카드 자동 접힘 - 리스트 맨 위 도달 시 카드 자동 펼쳐짐 - 참여 중인 같이방 영역 및 같이방/필터 영역 수직 스와이프로 접기/펼치기 가능 - 참여 중인 같이방 타이틀, 같이방 섹션, 필터는 항상 고정 표시 - 필터 하단 구분선은 리스트 스크롤 중일 때만 표시 - AnimatedContainer 기반 부드러운 전환 애니메이션 적용 --- lib/screens/wedu/wedu_home.dart | 228 ++++++++++++++++---------------- 1 file changed, 113 insertions(+), 115 deletions(-) diff --git a/lib/screens/wedu/wedu_home.dart b/lib/screens/wedu/wedu_home.dart index 068ec33..f919045 100644 --- a/lib/screens/wedu/wedu_home.dart +++ b/lib/screens/wedu/wedu_home.dart @@ -77,7 +77,7 @@ class _HomeWeduState extends State { !_isLoading) { loadMoreData(); } - if (_scrollController.offset == + if (_scrollController.offset <= _scrollController.position.minScrollExtent) { setState(() { _isUp = true; @@ -293,75 +293,124 @@ class _HomeWeduState extends State { } Widget bodyWidget() { - return Scaffold( - backgroundColor: PeeroreumColor.white, - appBar: roomBody(), - body: NestedScrollView( - physics: const AlwaysScrollableScrollPhysics(), - headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { - return [ - if (inRoomData.isNotEmpty) - SliverAppBar( - expandedHeight: 200, - pinned: false, - floating: true, - backgroundColor: PeeroreumColor.white, - elevation: 0, - flexibleSpace: LayoutBuilder( - builder: - (BuildContext context, BoxConstraints constraints) { - return FlexibleSpaceBar( - collapseMode: CollapseMode.parallax, - background: Column( - children: [ - SizedBox( - height: 180, - child: inRoomBody(), + return Column( + children: [ + if (inRoomData.isNotEmpty) ...[ + GestureDetector( + behavior: HitTestBehavior.translucent, + onVerticalDragEnd: (details) { + final dy = details.velocity.pixelsPerSecond.dy; + if (dy < -200 && _isUp) { + setState(() => _isUp = false); + } else if (dy > 200 && !_isUp) { + setState(() => _isUp = true); + } + }, + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + const Text( + "참여 중인 같이방", + style: TextStyle( + color: PeeroreumColor.black, + fontFamily: 'Pretendard', + fontSize: 18, + fontWeight: FontWeight.w600, ), - const SizedBox( - height: 20, + ), + const SizedBox(width: 4), + Text( + '${inRoomData.length}', + style: TextStyle( + fontFamily: 'Pretendard', + fontSize: 18, + fontWeight: FontWeight.w600, + color: PeeroreumColor.gray[600], ), - ], + ), + ], + ), + GestureDetector( + onTap: () => Get.to(() => const InWedu()), + child: Text( + '전체보기', + style: TextStyle( + fontFamily: 'Pretendard', + fontWeight: FontWeight.w600, + fontSize: 14, + color: PeeroreumColor.gray[500], + ), ), - ); - }, + ), + ], ), ), - ]; - }, - body: data.isEmpty - ? Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - sliver(), - Image.asset( - 'assets/images/no_wedu_oreum.png', - width: 150, - ), - const Text( - '찾으시는 같이방이 없어요 🥲', - style: TextStyle( - fontFamily: 'Pretendard', - fontSize: 20, - fontWeight: FontWeight.w600, - color: PeeroreumColor.black, + AnimatedContainer( + duration: const Duration(milliseconds: 150), + curve: Curves.easeInOut, + height: _isUp ? 200 : 0, + child: ClipRect( + child: OverflowBox( + maxHeight: 200, + alignment: Alignment.topCenter, + child: Column( + children: [ + SizedBox(height: 180, child: inRoomBody()), + const SizedBox(height: 20), + ], ), ), - ], - ) - : Column( - children: [ - sliver(), - Container( - height: _isUp ? 0 : 1, - color: PeeroreumColor.gray[200], - ), - Expanded(child: listViewBody()), - const SizedBox( - height: 8, - ), - ], - )), + ), + ), + ], + ), + ), + ], + GestureDetector( + behavior: HitTestBehavior.translucent, + onVerticalDragEnd: (details) { + final dy = details.velocity.pixelsPerSecond.dy; + if (dy < -200 && _isUp) { + setState(() => _isUp = false); + } else if (dy > 200 && !_isUp) { + setState(() => _isUp = true); + } + }, + child: sliver(), + ), + Container(height: _isUp ? 0 : 1, color: PeeroreumColor.gray[200]), + if (data.isEmpty) + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/images/no_wedu_oreum.png', + width: 150, + ), + const Text( + '찾으시는 같이방이 없어요 🥲', + style: TextStyle( + fontFamily: 'Pretendard', + fontSize: 20, + fontWeight: FontWeight.w600, + color: PeeroreumColor.black, + ), + ), + ], + ), + ) + else ...[ + Expanded(child: listViewBody()), + const SizedBox(height: 8), + ], + ], ); } @@ -395,58 +444,6 @@ class _HomeWeduState extends State { ); } - PreferredSizeWidget roomBody() { - return AppBar( - backgroundColor: PeeroreumColor.white, - shadowColor: Colors.transparent, - surfaceTintColor: Colors.transparent, - elevation: 0, - titleSpacing: 0, - automaticallyImplyLeading: false, - title: Padding( - padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - const Text( - "참여 중인 같이방", - style: TextStyle( - color: PeeroreumColor.black, - fontFamily: 'Pretendard', - fontSize: 18, - fontWeight: FontWeight.w600), - ), - const SizedBox( - width: 4, - ), - Text( - '${inRoomData.length}', - style: TextStyle( - fontFamily: 'Pretendard', - fontSize: 18, - fontWeight: FontWeight.w600, - color: PeeroreumColor.gray[600]), - ), - ], - ), - GestureDetector( - onTap: () { - Get.to(() => const InWedu()); - }, - child: Text('전체보기', - style: TextStyle( - fontFamily: 'Pretendard', - fontWeight: FontWeight.w600, - fontSize: 14, - color: PeeroreumColor.gray[500]))) - ], - ), - ), - ); - } - Widget inRoomBody() { return FutureBuilder( future: fetchInWeduData(), @@ -1200,3 +1197,4 @@ class _HomeWeduState extends State { super.dispose(); } } + From d639950b7ee059cbd31f5f9054c6f223f5099c36 Mon Sep 17 00:00:00 2001 From: ormee Date: Mon, 18 May 2026 13:10:01 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat(wedu):=20=EC=B0=B8=EC=97=AC=20?= =?UTF-8?q?=EC=A4=91=EC=9D=B8=20=EA=B0=99=EC=9D=B4=EB=B0=A9=20=EC=97=86?= =?UTF-8?q?=EC=9D=84=20=EB=95=8C=20=EB=B9=88=20=EC=83=81=ED=83=9C=20UI=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 참여 중인 같이방이 없을 때도 타이틀 영역 및 접힘/펼침 동작 유지 - 빈 상태 시 '참여 중인 같이방이 없어요' 안내 문구 및 '같이방 만들러 가기' 버튼 표시 --- lib/screens/wedu/wedu_home.dart | 169 +++++++++++++++++--------------- 1 file changed, 90 insertions(+), 79 deletions(-) diff --git a/lib/screens/wedu/wedu_home.dart b/lib/screens/wedu/wedu_home.dart index f919045..805b5de 100644 --- a/lib/screens/wedu/wedu_home.dart +++ b/lib/screens/wedu/wedu_home.dart @@ -5,6 +5,7 @@ import 'package:peeroreum_client/designs/PeeroreumToast.dart'; import 'package:get/get.dart'; import 'package:peeroreum_client/api/ApiClient.dart'; import 'package:peeroreum_client/designs/PeeroreumColor.dart'; +import 'package:peeroreum_client/designs/PeeroreumTypo.dart'; import 'package:peeroreum_client/screens/alert/alert_view.dart'; import 'package:peeroreum_client/screens/wedu/wedu_create_screen.dart'; import 'package:peeroreum_client/screens/wedu/wedu_in.dart'; @@ -295,83 +296,104 @@ class _HomeWeduState extends State { Widget bodyWidget() { return Column( children: [ - if (inRoomData.isNotEmpty) ...[ - GestureDetector( - behavior: HitTestBehavior.translucent, - onVerticalDragEnd: (details) { - final dy = details.velocity.pixelsPerSecond.dy; - if (dy < -200 && _isUp) { - setState(() => _isUp = false); - } else if (dy > 200 && !_isUp) { - setState(() => _isUp = true); - } - }, - child: Column( - children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - const Text( - "참여 중인 같이방", - style: TextStyle( - color: PeeroreumColor.black, - fontFamily: 'Pretendard', - fontSize: 18, - fontWeight: FontWeight.w600, - ), - ), - const SizedBox(width: 4), - Text( - '${inRoomData.length}', - style: TextStyle( - fontFamily: 'Pretendard', - fontSize: 18, - fontWeight: FontWeight.w600, - color: PeeroreumColor.gray[600], - ), - ), - ], - ), - GestureDetector( - onTap: () => Get.to(() => const InWedu()), - child: Text( - '전체보기', + GestureDetector( + behavior: HitTestBehavior.translucent, + onVerticalDragEnd: (details) { + final dy = details.velocity.pixelsPerSecond.dy; + if (dy < -200 && _isUp) { + setState(() => _isUp = false); + } else if (dy > 200 && !_isUp) { + setState(() => _isUp = true); + } + }, + child: Column( + children: [ + Padding( + padding: + const EdgeInsets.symmetric(vertical: 16, horizontal: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + T3_18px( + text: '참여 중인 같이방', + color: PeeroreumColor.gray[800], + ), + const SizedBox(width: 4), + Text( + '${inRoomData.length}', style: TextStyle( fontFamily: 'Pretendard', + fontSize: 18, fontWeight: FontWeight.w600, - fontSize: 14, - color: PeeroreumColor.gray[500], + color: PeeroreumColor.gray[600], ), ), - ), - ], - ), - ), - AnimatedContainer( - duration: const Duration(milliseconds: 150), - curve: Curves.easeInOut, - height: _isUp ? 200 : 0, - child: ClipRect( - child: OverflowBox( - maxHeight: 200, - alignment: Alignment.topCenter, - child: Column( - children: [ - SizedBox(height: 180, child: inRoomBody()), - const SizedBox(height: 20), - ], + ], + ), + GestureDetector( + onTap: () => Get.to(() => const InWedu()), + child: Text( + '전체보기', + style: TextStyle( + fontFamily: 'Pretendard', + fontWeight: FontWeight.w600, + fontSize: 14, + color: PeeroreumColor.gray[500], + ), ), ), + ], + ), + ), + AnimatedContainer( + duration: const Duration(milliseconds: 150), + curve: Curves.easeInOut, + height: _isUp ? 200 : 0, + child: ClipRect( + child: OverflowBox( + maxHeight: 200, + alignment: Alignment.topCenter, + child: inRoomData.isEmpty + ? SizedBox( + height: 200, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const T4_16px( + text: '참여 중인 같이방이 없어요', + color: PeeroreumColor.black), + const SizedBox(height: 20), + GestureDetector( + onTap: () => Get.to(() => CreateWedu()), + child: Container( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 16), + decoration: BoxDecoration( + color: PeeroreumColor.primaryPuple[400], + borderRadius: BorderRadius.circular(8), + ), + child: const T4_16px( + text: '같이방 만들러 가기', + color: PeeroreumColor.white), + ), + ), + ], + ), + ) + : Column( + children: [ + SizedBox(height: 180, child: inRoomBody()), + const SizedBox(height: 20), + ], + ), ), ), - ], - ), + ), + ], ), - ], + ), GestureDetector( behavior: HitTestBehavior.translucent, onVerticalDragEnd: (details) { @@ -426,17 +448,7 @@ class _HomeWeduState extends State { padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - '같이방', - style: TextStyle( - color: PeeroreumColor.gray[800], - fontSize: 18, - fontWeight: FontWeight.w600, - fontFamily: 'Pretendard', - ), - ), - ], + children: [T3_18px(text: '같이방', color: PeeroreumColor.gray[800])], ), ), dropDownBody(), @@ -1197,4 +1209,3 @@ class _HomeWeduState extends State { super.dispose(); } } - From 6de3157e7b76f677d33ab5bbe9da7dbe51e3e24f Mon Sep 17 00:00:00 2001 From: ormee Date: Mon, 18 May 2026 13:48:25 +0900 Subject: [PATCH 3/3] =?UTF-8?q?feat(wedu):=20=EA=B0=99=EC=9D=B4=EB=B0=A9?= =?UTF-8?q?=20=ED=83=AD=20=EB=B9=88=20=EC=83=81=ED=83=9C=20UI=20=EB=B0=8F?= =?UTF-8?q?=20=EB=B2=84=ED=8A=BC=20=EB=85=B8=EC=B6=9C=20=EC=A1=B0=EA=B1=B4?= =?UTF-8?q?=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 참여 중인 같이방 없을 때 빈 상태 문구 및 '같이방 만들러 가기' 버튼 표시 - 필터링 결과 없을 때 참여 중인 같이방이 있으면 하단에도 버튼 표시 - 참여/필터 모두 없을 때는 상단에만 버튼 표시 --- lib/screens/wedu/wedu_home.dart | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/screens/wedu/wedu_home.dart b/lib/screens/wedu/wedu_home.dart index 805b5de..62030f4 100644 --- a/lib/screens/wedu/wedu_home.dart +++ b/lib/screens/wedu/wedu_home.dart @@ -425,6 +425,23 @@ class _HomeWeduState extends State { color: PeeroreumColor.black, ), ), + if (inRoomData.isNotEmpty) ...[ + const SizedBox(height: 20), + GestureDetector( + onTap: () => Get.to(() => CreateWedu()), + child: Container( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 16), + decoration: BoxDecoration( + color: PeeroreumColor.primaryPuple[400], + borderRadius: BorderRadius.circular(8), + ), + child: const T4_16px( + text: '같이방 만들러 가기', + color: PeeroreumColor.white), + ), + ), + ], ], ), )