[Flutter] Drawer, SliverAppBar

Comely·2024년 11월 15일

Flutter

목록 보기
11/26

Drawer

drawer: Drawer(
              backgroundColor: statusModel.darkColor,
              child: ListView(
                children: [
                  DrawerHeader(
                    margin: EdgeInsets.zero,
                    child: Text(
                      '지역 선택',
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 20.0,
                      ),
                    ),
                  ),
                  ...Region.values
                      .map(
                        (e) => ListTile(
                          selected: e == region,
                          tileColor: Colors.white,
                          selectedTileColor: statusModel.lightColor,
                          selectedColor: Colors.black,
                          onTap: () {
                            setState(() {
                              region = e;
                            });
                            Navigator.of(context).pop();
                          },
                          title: Text(
                            e.krName,
                          ),
                        ),
                      )
                      .toList(),
                ],
              ),
            ),

Region

enum Region {
  daegu,
  chungnam,
  incheon,
  daejeon,
  gyeongbuk,
  sejong,
  gwangju,
  jeonbuk,
  gangwon,
  ulsan,
  jeonnam,
  seoul,
  busan,
  jeju,
  chungbuk,
  gyeongnam,
  gyeonggi;

  String get krName {
    switch (this) {
      case Region.daegu:
        return '대구';
      case Region.chungnam:
        return '충남';
      case Region.incheon:
        return '인천';
      case Region.daejeon:
        return '대전';
      case Region.gyeongbuk:
        return '경북';
      case Region.sejong:
        return '세종';
      case Region.gwangju:
        return '광주';
      case Region.jeonbuk:
        return '전북';
      case Region.gangwon:
        return '강원';
      case Region.ulsan:
        return '울산';
      case Region.jeonnam:
        return '전남';
      case Region.seoul:
        return '서울';
      case Region.busan:
        return '부산';
      case Region.jeju:
        return '제주';
      case Region.chungbuk:
        return '충북';
      case Region.gyeongnam:
        return '경남';
      case Region.gyeonggi:
        return '경기';
      default:
        throw Exception('존재하지 않는 지역 이름입니다.');
    }
  }
}

HomeScreen 전체코드

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  Region region = Region.seoul;
  bool isExpanded = true;
  ScrollController scrollController = ScrollController();

  
  void initState() {
    super.initState();

    StatRepository.fetchData();

    scrollController.addListener(() {
      bool isExpanded = scrollController.offset < (500 - kToolbarHeight);

      if(isExpanded != this.isExpanded){
        setState(() {
          this.isExpanded = isExpanded;
        });
      }
    });
  }

  
  Widget build(BuildContext context) {
    return FutureBuilder<StatModel?>(
        future: GetIt.I<Isar>()
            .statModels
            .filter()
            .regionEqualTo(region)
            .itemCodeEqualTo(ItemCode.PM10)
            .sortByDateTimeDesc()
            .findFirst(),
        builder: (context, snapshot) {
          if (!snapshot.hasData) {
            return Scaffold(
              body: CircularProgressIndicator(),
            );
          }

          final statModel = snapshot.data!;
          final statusModel =
              StatusUtils.getStatusModelFromStat(statModel: statModel);

          return Scaffold(
            drawer: Drawer(
              backgroundColor: statusModel.darkColor,
              child: ListView(
                children: [
                  DrawerHeader(
                    margin: EdgeInsets.zero,
                    child: Text(
                      '지역 선택',
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 20.0,
                      ),
                    ),
                  ),
                  ...Region.values
                      .map(
                        (e) => ListTile(
                          selected: e == region,
                          tileColor: Colors.white,
                          selectedTileColor: statusModel.lightColor,
                          selectedColor: Colors.black,
                          onTap: () {
                            setState(() {
                              region = e;
                            });
                            Navigator.of(context).pop();
                          },
                          title: Text(
                            e.krName,
                          ),
                        ),
                      )
                      .toList(),
                ],
              ),
            ),
            backgroundColor: statusModel.primaryColor,
            body: CustomScrollView(
              controller: scrollController,
              slivers: [
                MainStat(
                  region: region,
                  primaryColor: statusModel.primaryColor,
                  isExpanded: isExpanded,
                ),
                SliverToBoxAdapter(
                  child: Column(
                    children: [
                      CategoryStat(
                        region: region,
                        darkColor: statusModel.darkColor,
                        lightColor: statusModel.lightColor,
                      ),
                      HourlyStat(
                        region: region,
                        darkColor: statusModel.darkColor,
                        lightColor: statusModel.lightColor,
                      ),
                    ],
                  ),
                ),
              ],
            ),
          );
        });
  }
}

지금까지 Drawer의 간단한 설정을 알아봤습니다.
추가로 SliverAppBar 설정을 적용합니다.

SliverAppBar

AppBar 영역의 이미지가 스크롤로 사라지더라도 지역이름이 appbar에 표시됩니다.
생성자에 isExpanded 값을 받습니다.

main_stat.dart

const MainStat({
    super.key,
    required this.isExpanded,
  });
------------------------------------------------------------
return SliverAppBar(
      backgroundColor: primaryColor,
      expandedHeight: 500,
      pinned: true,
      title: isExpanded ? null : Text('${region.krName}'),
      flexibleSpace: FlexibleSpaceBar(
        background: SafeArea( 
        ...
------------------------------------------------------------      
   //kToolbarHeight 만큼 간격을 띄우고 이미지를 표시
   return Column(
                  children: [
                    SizedBox(
                      height: kToolbarHeight,
                    ),

homescreen.dart

  • bool isExpanded = true;
  • kToolbarHeight 기본 앱바의 높이
scrollController.addListener(() {
      bool isExpanded = scrollController.offset < (500 - kToolbarHeight);

      if(isExpanded != this.isExpanded){
        setState(() {
          this.isExpanded = isExpanded;
        });
profile
App, Web Developer

0개의 댓글