일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Flutter #플러터 #모바일앱만들기 #GetX
- 플레이스토어 앱등록
- 플러터 #Flutter #파이어베이스 #firebase #firestore #파이어스토어
- 앱번들
- GetX #CustomScrollView #Flutter
- 초성게임앱 #플러터앱 #플러터카운트다운
- Flutter #플러터 #프로젝트 #파이어베이스 #파이어스토어 #Firebase #FireStore
- flutter #android #androidstudio
- 유니티게임 #상점만들기 #뽑기구현 #케이디리듬게임
- AAB
- 복권번호예측 #Flutter #플러터 #Provider
- 복권번호예측기 #Flutter #adMob #광고배너 #리워드형광고
- Today
- Total
이코노딩
[Flutter Project] 애미티 앱 Getx 적용하기 - Custom 본문
😶기존의 Drawer와 DropDown 기능을 Custom하기 힘들어 원하는 디자인을 직접 구현해보기로 하였다.
라이브러리를 가져와 쓰려고 했다가, 간단하게 만들 수 있을 것 같아서 그대로 사용하기로했다.
✅CustomDrawer
기존 앱들에서 좌측에 숨겨져있다가 어떠한 액션 이벤트에 반응하여 나오는 서랍 느낌이다.
버튼을 눌렀을 나오는 더보기 버튼 처럼 만들었다.
☑️동작 구상
동작은 간단하게 버튼을 눌렀을 때, 페이지를 이동하는데 애니메이션을 주고 또 이동 옵션 중, opaque를 false로 주어서 이전 화면이 그대로 유지 될 수 있도록하였다.
그리고 Drawer페이지에서는 Stack과 Position위젯으로 위치를 조정해 주었다.
☑️라우팅 코드
페이지 이동시 애니메이션은 fade가 가장 자연스러웠다.
InkWell(
onTap: (){
Get.to(()=>const More(), opaque: false, fullscreenDialog: true, transition: Transition.fade, curve: Curves.linear);
},
child: Icon(Icons.more_vert, color: const Color(0xffaecdff), size: 28.r,),
)
☑️More() - Code
클래스 이름은 간단하게 More로 만들었다. 상태 변화가 없기 때문에, 변수나 리로드를 해줄 필요가 없다.
GestureDetector( //버튼 외 터치시 페이지를 닫을 수 있도록 전체를 감싸 줌
onTap: ()=> Get.back(),
child: Material( //Material 하위 위젯을 사용해야함
color: Colors.transparent, // 뒷배경은 투명하게
child: Stack(
children: [
SizedBox( //화면 전영역을 사용하기 위한 공간확복
width: Get.width,
height: Get.height,
),
Positioned( //원하는 위치에 버튼 추가하기
top: 50.h, right: 10.w,
child: Column(
children: [
//벌칙 설정 버튼
DelayedWidget(
animation: DelayedAnimations.SLIDE_FROM_RIGHT,
animationDuration: const Duration(milliseconds: 300),
delayDuration: const Duration(milliseconds: 100),
child: InkWell(
onTap: (){}, //터치시 벌칙 설정 페이지로이동
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.all(20.r),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Color(0xffaecdbb)
),
child: Column(
children: [
Icon(Icons.hardware, size: 24.r, color: const Color(0xffffffff),),
SizedBox(height: 5.h,),
Text('벌칙 설정', style: TextStyle(fontSize: 12.sp, fontWeight: FontWeight.bold, color: const Color(0xffffffff)),)
],
),
),
),
),
SizedBox(height: 20.h,),
///커스텀설정 버튼
DelayedWidget(
animation: DelayedAnimations.SLIDE_FROM_RIGHT,
animationDuration: const Duration(milliseconds: 300),
delayDuration: const Duration(milliseconds: 200),
child: InkWell(
onTap: (){},//터치시 커스텀 설정 페이지 이동
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.all(20.r),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Color(0xffaecdcc)
),
child: Column(
children: [
Icon(Icons.person, size: 24.r, color: const Color(0xffffffff),),
SizedBox(height: 5.h,),
Text('커스텀 설정', style: TextStyle(fontSize: 12.sp, fontWeight: FontWeight.bold, color: const Color(0xffffffff)),)
],
),
),
),
),
SizedBox(height: 20.h,),
///앱정보 버튼
DelayedWidget(
animation: DelayedAnimations.SLIDE_FROM_RIGHT,
animationDuration: const Duration(milliseconds: 300),
delayDuration: const Duration(milliseconds: 300),
child: InkWell(
onTap: (){},//터치시 앱정보 페이지 이동
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.all(20.r),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: const Color(0xffffffff),
border: Border.all(width: 2,color: const Color(0xffaecdff))
),
child: Column(
children: [
Image.asset('assets/images/sub_icon.png', width: 30.r, height: 30.r,),
SizedBox(height: 5.h,),
Text('앱 정보', style: TextStyle(fontSize: 12.sp, fontWeight: FontWeight.bold, color: const Color(0xffaecdff)),)
],
),
),
),
)
],
)
),
],
),
),
);
☑️결과
✅ CustomDropDown
앱 제작 중에 DropDown위젯을 많이 사용해야 하는데,
기존 위젯은 너무 안 어울려서 이것도 새롭게 커스텀 해보기로 하였다.
☑️동작 구상
위 Drawer처럼 클릭 시 새로운 페이지로 이동하여 선택할 수 있게 구현, 하지만 Drawer보다 DropDown리스트의 변경과 사용이 잦아서 라이브러리 처럼 그때 그때 쓸 수있는 형태로 제작
☑️CustomDropDown() - 변수
const CustomDropDown({Key? key, required this.list, required this.posX, required this.posY, required this.width, required this.height, required this.itemheight}) : super(key: key);
final List<String> list; //드롭다운리스트를 List<String>형으로 담을 변수
final double posX; //드롭다운 위치는 터치 된 컨테이너에서 나와야함으로 그에 따른 X좌표 받을 변수
final double posY; //위와 같은 이유의 Y좌표
final double width; //드롭다운의 전체 넓이
final double height; //드롭다운의 전체 높이
final double itemheight; //드로다운 아이템의 높이
☑️CustomDropDown() - Code
Material(
color: const Color(0xffffffff).withOpacity(0.4), //뒷배경을 살짝 불투명하게 만들어 드롭다운에 포커스가 됨
child: Stack(children: [
Positioned(
top: 0,
bottom: 0,
right: 0,
left: 0,
child: GestureDetector(
onTap: ()=> Get.back(),
child: Container()),
),
Positioned(
left: posX,
top: posY,
child: Container(
decoration: BoxDecoration(
border: Border.all(color: const Color(0xffaecdff)),
borderRadius: BorderRadius.circular(10),
color: Colors.white
),
height: height,
width: width,
child: CustomScrollView(
slivers: [
SliverFixedExtentList(
itemExtent: itemheight,
delegate: SliverChildBuilderDelegate((ctx, index) {
return DelayedWidget(
delayDuration: Duration(milliseconds: index * 10),
animationDuration:
const Duration(milliseconds: 100),
animation: DelayedAnimations.SLIDE_FROM_BOTTOM,
child: InkWell(
onTap: () {
Get.back(result: list[index]);
},
child: Container(
alignment: Alignment.center,
color: Colors.transparent,
child: Text(
list[index],
style: TextStyle(fontSize: 13.sp),
),
),
));
}, childCount: list.length))
],
),
))
]));
☑️ 라우팅 코드
GestureDetector(
onTap: () async{
final result = await Get.to(()=>CustomDropDown(list: controller.numberList,
posX: controller.getPosX(),
posY: controller.getPosY(),
width: 130.h,
height: 120.w,
itemheight: 30.h), opaque: false, fullscreenDialog: true, transition: Transition.fadeIn);
if(result != ''){
controller.numberPlayer.value = int.parse(result);
}
}
오류 코드를 찾기 편하게 하기위해 위젯들을 클래스 단위로 쪼게 구현 하였다.
PlayerWidget을 만들어 GetxController를 선언해준뒤 상태변화 변수들과 함수들을 정의해 주었다.
그리고 리스트의 결과를 비동기로 처리하여 결과를 불러올 수 있게 만들었다.
☑️필요 함수
//드롭다운될 Container Key
final dropdownKey = GlobalKey();
///드롭다운될 Container 좌표받기
double getPosY(){
var box = dropdownKey.currentContext!.findRenderObject();
var translation = box!.getTransformTo(null).getTranslation();
return box.paintBounds.shift(Offset(translation.x,translation.y)).bottomCenter.dy;
}
double getPosX(){
var box = dropdownKey.currentContext!.findRenderObject();
var translation = box!.getTransformTo(null).getTranslation();
return box.paintBounds.shift(Offset(translation.x,translation.y)).bottomLeft.dx;
}
☑️결과
❌오류 및 개선
플레이어 선택 시 테두리가 변화를 안한다. Obx안 감싸줘서 그런 듯,
hint text의 스타일을 바꿔 줘야할거 같다.
개선 후 게임 제작 해야징
'프로젝트 > 애미티' 카테고리의 다른 글
[Flutter Project] DropDown Button2 Package (0) | 2023.03.15 |
---|---|
[Flutter Project] Scroll Navigation Package (0) | 2023.03.15 |
[Flutter Project] 애미티앱 GetX 적용하기 - 초성게임 (0) | 2023.03.07 |
[Flutter Project]애미티 앱 GetX 적용하기 - UI 구상 (0) | 2023.02.02 |
[Flutter] Amity앱에 GetX 적용해보기 (0) | 2023.01.30 |