-
Notifications
You must be signed in to change notification settings - Fork 0
[UI] 작성한 프로필 확인 화면 #46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 하나의 섹션 단위를 한 파일에 두는 것보다 따로 두는게 더 구조파악하기에 좋을 것 같습니돠 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,270 @@ | ||
| import 'package:code_l/core/utills/design/app_gaps.dart'; | ||
| import 'package:code_l/core/utills/design/app_typography.dart'; | ||
| import 'package:code_l/sign_up/presentation/pages/profile_summary/widgets/profile_summary_app_bar.dart'; | ||
| import 'package:flutter/cupertino.dart'; | ||
| import 'package:flutter/material.dart'; | ||
|
|
||
| import '../../../../core/utills/design/app_colors.dart'; | ||
|
|
||
| class ProfileSummaryPage extends StatelessWidget { | ||
| ProfileSummaryPage({Key? key}) : super(key: key); | ||
| final PageController pageController = PageController(); | ||
| final ValueNotifier<int> currentPageNotifier = ValueNotifier<int>(0); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. currentPage라는 느낌보다 해당 변수가 사진의 개수를 나타내는거니까.. 음 profileImageIndex 정도.. |
||
| @override | ||
| Widget build(BuildContext context) { | ||
| return Scaffold( | ||
| appBar: ProfileSummaryAppBar(), | ||
| body: SingleChildScrollView( | ||
| child: Column( | ||
| crossAxisAlignment: CrossAxisAlignment.start, | ||
| children: [ | ||
| buildCodeProfileImage([ | ||
| 'https://i.namu.wiki/i/26zrz9vXNoJuC8XAawLsvE54JAHRKgQZcpx0SQ1g60r3Nn80nqpXFK0VBulBYNuuayrcCpli4u8jUMUm_1n5CIo84vxWbQcN46w0Ah_VS2hJZ0m88_jTWwKWtij1_m38H1G-Py_8fdiHrSWKyWAWCQ.webp', | ||
| 'https://i.namu.wiki/i/26zrz9vXNoJuC8XAawLsvE54JAHRKgQZcpx0SQ1g60r3Nn80nqpXFK0VBulBYNuuayrcCpli4u8jUMUm_1n5CIo84vxWbQcN46w0Ah_VS2hJZ0m88_jTWwKWtij1_m38H1G-Py_8fdiHrSWKyWAWCQ.webp', | ||
| 'https://i.namu.wiki/i/26zrz9vXNoJuC8XAawLsvE54JAHRKgQZcpx0SQ1g60r3Nn80nqpXFK0VBulBYNuuayrcCpli4u8jUMUm_1n5CIo84vxWbQcN46w0Ah_VS2hJZ0m88_jTWwKWtij1_m38H1G-Py_8fdiHrSWKyWAWCQ.webp', | ||
| ]), | ||
| Column( | ||
| crossAxisAlignment: CrossAxisAlignment.start, | ||
| children: [ | ||
| buildNameAge(), | ||
| Container(height: AppGaps.gap8, color: AppColors.grey100), | ||
| buildIntroduce(), | ||
| Container(height: AppGaps.gap8, color: AppColors.grey100), | ||
| buildProfileFaceImage(), | ||
| Container(height: AppGaps.gap8, color: AppColors.grey100), | ||
| buildProfileSection('사용가능코드네임의 LIFE', [ | ||
| buildListItem('직업', '학생'), | ||
| buildListItem('음주여부', '유산소 즐기는 매니아'), | ||
| buildListItem('흡연여부', '유산소 즐기는 매니아'), | ||
| buildListItem('MBTI', 'ENTJ'), | ||
| ]), | ||
| Container(height: AppGaps.gap8, color: AppColors.grey100), | ||
| buildProfileSection('사용가능코드네임의 LIKE', [ | ||
| buildListItem('취향', '운동, 독서 & 글쓰기, IT기술'), | ||
| buildListItem('활동지역', '서울특별시 강동구'), | ||
| ]), | ||
| Container(height: AppGaps.gap8, color: AppColors.grey100), | ||
| buildProfileSection('사용가능코드네임의 LIFESTYLE', [ | ||
| buildListItem('연애가치관', '서로의 성장을 지원하는 스타일'), | ||
| buildListItem('애정표현', '나만 따라와 데이트 스타일'), | ||
| buildListItem('연락', '나만 따라와 데이트 스타일'), | ||
| buildListItem('데이트', '나만 따라와 데이트 스타일'), | ||
| buildListItem('갈등해결', '나만 따라와 데이트 스타일'), | ||
| buildListItem('사랑의 언어', '나만 따라와 데이트 스타일'), | ||
| ]), | ||
| ], | ||
| ), | ||
| ], | ||
| ), | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| Widget buildNameAge() { | ||
| return Padding( | ||
| padding: const EdgeInsets.all(AppGaps.gap16), | ||
| child: Row( | ||
| mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
| children: [ | ||
| Row( | ||
| children: [ | ||
| Text('사용가능코드네임', style: AppTypography.header3), | ||
| SizedBox(width: AppGaps.gap8), | ||
| Text("26세", style: AppTypography.body2), | ||
| ], | ||
| ), | ||
| IconButton(icon: Icon(Icons.more_vert), onPressed: () {}), | ||
| ], | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| Widget buildIntroduce() { | ||
| return Padding( | ||
| padding: const EdgeInsets.all(AppGaps.gap16), | ||
| child: Column( | ||
| crossAxisAlignment: CrossAxisAlignment.start, | ||
| children: [ | ||
| buildSectionTitle('사용가능코드네임의 소개'), | ||
| SizedBox(height: AppGaps.gap8), | ||
| Text('방가방가', style: AppTypography.subtitle3), | ||
| ], | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| Widget buildProfileFaceImage() { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ProfileImage로 통일하면 Face가 먼저 나오는게 좋을 것 같아요 ! |
||
| return Padding( | ||
| padding: const EdgeInsets.all(AppGaps.gap16), | ||
| child: Column( | ||
| crossAxisAlignment: CrossAxisAlignment.start, | ||
| children: [ | ||
| buildSectionTitle('사용가능코드네임의 페이스 인증 이미지'), | ||
| SizedBox(height: AppGaps.gap12), | ||
| buildFaceProfileImages([ | ||
| 'https://i.namu.wiki/i/26zrz9vXNoJuC8XAawLsvE54JAHRKgQZcpx0SQ1g60r3Nn80nqpXFK0VBulBYNuuayrcCpli4u8jUMUm_1n5CIo84vxWbQcN46w0Ah_VS2hJZ0m88_jTWwKWtij1_m38H1G-Py_8fdiHrSWKyWAWCQ.webp', | ||
| 'https://i.namu.wiki/i/26zrz9vXNoJuC8XAawLsvE54JAHRKgQZcpx0SQ1g60r3Nn80nqpXFK0VBulBYNuuayrcCpli4u8jUMUm_1n5CIo84vxWbQcN46w0Ah_VS2hJZ0m88_jTWwKWtij1_m38H1G-Py_8fdiHrSWKyWAWCQ.webp', | ||
| 'https://i.namu.wiki/i/26zrz9vXNoJuC8XAawLsvE54JAHRKgQZcpx0SQ1g60r3Nn80nqpXFK0VBulBYNuuayrcCpli4u8jUMUm_1n5CIo84vxWbQcN46w0Ah_VS2hJZ0m88_jTWwKWtij1_m38H1G-Py_8fdiHrSWKyWAWCQ.webp', | ||
| ]), | ||
| SizedBox(height: AppGaps.gap12), | ||
| Container( | ||
| color: AppColors.grey100, | ||
| height: 24, | ||
| width: double.infinity, | ||
| alignment: Alignment.centerLeft, | ||
| child: Padding( | ||
| padding: const EdgeInsets.only(left: AppGaps.gap8), | ||
| child: Text( | ||
| "페이스 인증 이미지는 다른 사용자들에게 보이지 않아요!", | ||
| style: AppTypography.caption3.copyWith( | ||
| color: AppColors.grey500, | ||
| ), | ||
| ), | ||
| ), | ||
| ), | ||
| ], | ||
| ), | ||
| ); | ||
| } | ||
| Widget buildFaceProfileImages(List<String> imagePath) { | ||
| return Row( | ||
| children: List.generate( | ||
| imagePath.length, | ||
| (index) => buildFaceProfileImage(imagePath[index]), | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| Widget buildCodeProfileImage(List<String> imagePaths) { | ||
| return AspectRatio( | ||
| aspectRatio: 7 / 6, | ||
| child: Stack( | ||
| children: [ | ||
| PageView.builder( | ||
| controller: pageController, | ||
| itemCount: imagePaths.length, | ||
| onPageChanged: (index) { | ||
| currentPageNotifier.value = index; // 페이지 번호 업데이트 | ||
| }, | ||
| itemBuilder: (context, index) { | ||
| return Image.network( | ||
| imagePaths[index], | ||
| fit: BoxFit.cover, | ||
| ); | ||
| }, | ||
| ), | ||
| Align( | ||
| alignment: Alignment.topLeft, | ||
| child: ValueListenableBuilder<int>( | ||
| valueListenable: currentPageNotifier, | ||
| builder: (context, currentPage, _) { | ||
| return currentPageNotifier.value == 0 | ||
| ? Container( | ||
| margin: const EdgeInsets.all(8.0), | ||
| padding: const EdgeInsets.symmetric( | ||
| horizontal: 12.0, vertical: 6.0), | ||
| decoration: BoxDecoration( | ||
| color: Colors.black.withOpacity(0.6), | ||
| ), | ||
| child: Text( | ||
| '대표', | ||
| style: | ||
| AppTypography.body2.copyWith(color: Colors.white), | ||
| ), | ||
| ) | ||
| : Container(); | ||
| }, | ||
| ), | ||
| ), | ||
| Align( | ||
| alignment: Alignment.bottomCenter, | ||
| child: ValueListenableBuilder<int>( | ||
| valueListenable: currentPageNotifier, | ||
| builder: (context, currentPage, _) { | ||
| return Container( | ||
| margin: const EdgeInsets.all(8.0), | ||
| padding: const EdgeInsets.symmetric( | ||
| horizontal: 12.0, vertical: 6.0), | ||
| decoration: BoxDecoration( | ||
| color: Colors.black.withOpacity(0.6), | ||
| borderRadius: BorderRadius.circular(12.0), | ||
| ), | ||
| child: Text( | ||
| '${currentPage + 1} / ${imagePaths.length}', | ||
| style: AppTypography.body2.copyWith(color: Colors.white), | ||
| ), | ||
| ); | ||
| }, | ||
| ), | ||
| ), | ||
| ], | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| Widget buildSectionTitle(String title) { | ||
| return Text( | ||
| title, | ||
| style: AppTypography.subtitle3.copyWith(color: AppColors.primary), | ||
| ); | ||
| } | ||
|
|
||
| Widget buildFaceProfileImage(String imagePath) { | ||
| return Padding( | ||
| padding: const EdgeInsets.only(right: 8.0), | ||
| child: ClipRRect( | ||
| borderRadius: BorderRadius.circular(24), | ||
| child: Container( | ||
| width: 64, | ||
| height: 64, | ||
| decoration: BoxDecoration( | ||
| image: DecorationImage( | ||
| image: NetworkImage(imagePath), | ||
| fit: BoxFit.cover, | ||
| ), | ||
| ), | ||
| ), | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| Widget buildProfileSection(String title, List<Widget> items) { | ||
| return Padding( | ||
| padding: const EdgeInsets.all(AppGaps.gap16), | ||
| child: Column( | ||
| crossAxisAlignment: CrossAxisAlignment.start, | ||
| children: [ | ||
| buildSectionTitle(title), | ||
| SizedBox(height: AppGaps.gap8), | ||
| ...items, | ||
| SizedBox(height: AppGaps.gap16), | ||
| ], | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| Widget buildListItem(String key, String value) { | ||
| return Padding( | ||
| padding: const EdgeInsets.symmetric(vertical: 4.0), | ||
| child: Row( | ||
| children: [ | ||
| SizedBox( | ||
| width: 80, // key의 고정 너비 설정 | ||
| child: Text( | ||
| key, | ||
| style: AppTypography.subtitle3.copyWith(color: AppColors.grey500), | ||
| textAlign: TextAlign.left, | ||
| ), | ||
| ), | ||
| Expanded( | ||
| child: Text( | ||
| value, | ||
| style: AppTypography.subtitle3, | ||
| textAlign: TextAlign.left, | ||
| ), | ||
| ), | ||
| ], | ||
| ), | ||
| ); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| import 'package:code_l/core/utills/design/app_gaps.dart'; | ||
| import 'package:flutter/material.dart'; | ||
|
|
||
| import '../../../../../core/utills/design/app_colors.dart'; | ||
| import '../../../../../core/utills/design/app_typography.dart'; | ||
|
|
||
| class ProfileSummaryAppBar extends StatelessWidget | ||
| implements PreferredSizeWidget { | ||
| const ProfileSummaryAppBar({super.key}); | ||
|
|
||
| @override | ||
| Size get preferredSize => Size.fromHeight(56); | ||
| @override | ||
| Widget build(BuildContext context) { | ||
| return SafeArea( | ||
| child: Padding( | ||
| padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), | ||
| child: Row( | ||
| mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
| crossAxisAlignment: CrossAxisAlignment.center, | ||
| children: [ | ||
| SizedBox(width: AppGaps.gap36), | ||
| Text( | ||
| "내가 작성한 코드프로필", | ||
| style: AppTypography.subtitle2.copyWith(color: AppColors.grey900), | ||
| ), | ||
| IconButton( | ||
| icon: const Icon(Icons.close), | ||
| onPressed: () { | ||
| Navigator.pop(context); | ||
| }, | ||
| ), | ||
| ], | ||
| ), | ||
| ), | ||
| ); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 부분은 다시 currentPage를 넣어줘야 할듯요 !