프로젝트/애미티
[Flutter Project]애미티 앱 GetX 적용하기 - UI 구상
떼이로
2023. 2. 2. 20:47
✅UI 구상하기
☑️ Class - Home() : 필요한 위젯
✔️ Home은 안에 PageView Widget과 Page 이동을 시각적으로 보여주는 Widget
✔️ Drawer를 꺼낼 수 있는 Button
✔️ 애니메이션을 라이브러리 위젯 DelayedWidget: https://pub.dev/packages/delayed_widget
☑️Class - Home() : Code
✔️ StatelessWidget에서 화면 구상, GetxController로 상태관리
class Home extends StatelessWidget {
Home({Key? key}) : super(key: key);
final controller = Get.put(HomeController());
✔️ 가장 상단(AppBar 위치)에는 Page 이동을 시각적으로 나타내줄 Widget배치
//Scaffold
AppBar(
leadingWidth: 0,
backgroundColor: const Color(0xffffffff),
toolbarHeight: 60.h, //.h는 ScreenUtil 라이브러리
automaticallyImplyLeading: false,
centerTitle: true,
elevation: 0,
//타이틀 내에 리스트뷰를 이용하여 구상
title: SizedBox(
height: 60.h,
width: Get.width, //MediaQuery.of(context).size.width랑 같음
child: ListView.separated(
physics: const NeverScrollableScrollPhysics(), //스크롤 고정
scrollDirection: Axis.horizontal, //방향은 가로
itemBuilder: (context, index) => Obx( //Rx자료형은 이런식으로 Obx내에 있으면 상태변화를 감시할 수 있음
()=> InkWell(
onTap: (){
controller.pageIndex.value = index;
//page 이동에 애니메이션을 위해
controller.pageController.animateToPage(index, duration: const Duration(milliseconds: 300), curve: Curves.linear);
},
child: AnimatedContainer(
duration: const Duration(milliseconds: 500),
padding: EdgeInsets.symmetric(horizontal: 10.w),
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 3,
color: controller.pageIndex.value == index ? const Color(0xffaecfff) : Colors.transparent
)
)
),
child: Row(
children: [
controller.pageIndex.value == index ?
DelayedWidget(
delayDuration: const Duration(milliseconds: 100),
animation: DelayedAnimations.SLIDE_FROM_LEFT,
animationDuration: const Duration(milliseconds: 300),
child: Image.asset('assets/images/sub_icon.png', width: 20.r, height: 20.r,)) : Container(),
Text(
controller.game[index], style: TextStyle(
fontSize: controller.pageIndex.value == index ? 18.sp : 13.sp,
fontWeight: controller.pageIndex.value == index ? FontWeight.bold : FontWeight.normal,
color: controller.pageIndex.value == index ? const Color(0xffaecdff) : const Color(0xffdddddd)
),
),
],
),
),
),
),
separatorBuilder: (context, index) => Container(),
itemCount: controller.game.length),
)
),
✔️ 아래에는 공통적인 TEXT와 Drawer를 위한 버튼과 PageView (:코드 생략)
☑️Class - HomeController() : Code
✔️ 변수
//pageview controller
PageController pageController = PageController(initialPage: 0);
//game list
final List<String> game = ['초성게임', '폭탄게임', '몸으로말해요', '가요능력평가'];
//RX형의 페이지 인덱스
RxInt pageIndex = 0.obs;
✔️ 그 외
void onInit() {
// TODO: implement onInit
super.onInit();
//controller가 실행되면 리스너 등록
pageController.addListener(() {
pageIndex.value = pageController.page!.toInt();
});
}
✅ 결과
☑️ 고쳐야할 부분
❌ 버튼을 통한 페이지 이동시 애니메이션이 너무 크다.
#️⃣ 다음엔 Drawer과 DropDown을 Custom으로 만드는 방법에 대해 정리