프로젝트/애미티

[Flutter Project]애미티 앱 GetX 적용하기 - UI 구상

떼이로 2023. 2. 2. 20:47

✅UI 구상하기

 

초기 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으로 만드는 방법에 대해 정리