플러터로 토스같은 앱바 만들기<2>

enoch·2021년 6월 30일
2

플러터

목록 보기
2/17

저번에 이어서, 본격적으로 앱바 만들기를 시작해보려고 한다.

우선 이 앱바가 사용될곳이 여러개의스크롤 영역을 사용한다면 제일위에 CustomScrollView로 감싸야하고 그렇지않다면 SingleChildScrollView를 사용해도 무방하다.

먼저 설명하기전 구조를 말하자면

Scaffold(플러터 기본적인 구조)
:emptyAppbar(전 시간에 만들어둔 빈 앱바)
⎿SafeArea(노치영역을 제외한 구역)
  ⎿Stack(위젯을 겹치게 배치가 가능해짐)
    ⎿ScrollView(CustomScrollView|SingleChildScrollView...)
      ⎿(스크롤전 보여지는 앱바)
      ⎿(메인 컨텐츠)
    ⎿Positioned(stack을이용해서 제일위에다가 앱바를 위치시킴)
      ⎿(스크롤후 보여지는 앱바)

이런식의 구조를 사용하게 된다.

먼저 해당 구조가 포함되어있는 위젯은 stateful로 작성해야지 스크롤이 제일 위로 향했는지 구별할수있는 변수를 활용가능하다 (stateful은 말그대로 상태가 있을수있는 위젯, setstate를 활용한 상태변경이 가능한 위젯)

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  bool _isTop = true;
...
...

앞에 언더바를 붙이면 python 처럼 프라이빗 변수로 활용 가능하다.

그리고 ScrollView 부분은 따로 컴포넌트로 분리해서 관리하게 만들었다.

import 'package:flutter/material.dart';

import '../../constant.dart';

class CustomPage extends StatefulWidget {
  const CustomPage({Key? key,required this.children,required this.setTop}) : super(key: key);
  //부모 위젯에서 children 을 받을수있게 설정해두었고, 
  //setTop은 콜백형식으로 받아서 자식위젯에서도 변경 가능하게 만들었다
  final BoolCallback setTop;
  final List<Widget> children;
  @override
  _CustomPageState createState() => _CustomPageState();
}

class _CustomPageState extends State<CustomPage> {
  late ScrollController _scrollController;
//스크롤 컨트롤을 위한 컨트롤러 선언. 
//NULL이될수없는 인스턴스는 초기화하거나 혹은 late를 사용하거나 생성자에서 초기화해야한다. 
  @override
  void initState(){
    super.initState();
    _scrollController = new ScrollController();
    //이벤트를 등록해서 스크롤의 위치를 감지
    _scrollController.addListener(() {
      if(_scrollController.offset<=0.0){
      //튕겨나가는 효과를 더하기위해서 offset이 마이너스일때까지 top으로 지정
        widget.setTop(true);
        //stateful위젯에서 받아온 변수들을 사용하려면 widget클래스를 사용해야한다.
      }
      else{
        widget.setTop(false);
      }
    });
  }
  
  @override
  void dispose(){
    _scrollController.removeListener(() { });
    _scrollController.dispose();
    super.dispose();
    //컨트롤러 이벤트 삭제 부분.
  }
  
  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      physics: BouncingScrollPhysics(),
      //스크롤이 튕기는효과
      controller: _scrollController,
      slivers:widget.children,
      //customScrollView를 사용하면 children이아닌 slivers에다가 위젯을 집어넣는다.
      //sliver안에는 무조건 sliver object를 넣어야하기때문에 container같은 위젯은 따로 
      //설정을 해주어야한다
    );
  }
}

이렇게 만들어두면 해당 스크롤뷰에서 스크롤이 제일 위로 갔을경우 부모위젯에서 _isTop이 true가 된다.
그럼 앱바를 만들 준비가 거의 끝!

저도 공부하면서 하는거라 허접한부분이 많을수도..

profile
플러터존잼

2개의 댓글

comment-user-thumbnail
2021년 10월 23일

안녕하세요. flutter 공부하고 있는 학생인데요. 해당 앱바가 너무 마음에 들어서 열심히 연구해 보고 있는데 잘 구현이 되지 않네요 ㅠㅠ 혹시 해당 앱 소스코드를 참고할 수 있을까요?

1개의 답글