개발아빠/Flutter

[Flutter] 공통 AppBar 만들기 aka BaseAppBar

육아개발아빠 2021. 2. 9. 10:41
반응형

안녕하세요.

개발아빠입니다.

 

오늘은 화면마다 많이 쓰이는 AppBar를 재사용이 편하게 공통으로 한번 만들어 볼려고합니다.

페이지별로 특이하지는 않지만, 매번 AppBar를 만들던 비효율에서 이제는 청산해 볼려고 합니다.

 

AppBar 지옥 안녕.!

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
      leading: IconButton(
        icon: Image.asset("assets/images/ic_chevron_30_back.png", width: 24, height: 24,),
        onPressed: () => Navigator.of(context).pop(),
      ),
      centerTitle: center,
      title: Text("$title", style: TextStyle(color: Colors.black, fontSize: 18.0, fontWeight: FontWeight.w700),),
      );
      body: Container()
    );
  }

 

 

아마 앱 내에서 사용할 여러가지 위젯들을 재사용성이 높게 새로운 위젯으로 개발을 하시겠지만,

AppBar를 만드는 방식은 약간 달라서 포스팅을 하게 되었습니다.

 

기본적으로 위젯을 만든다는 것과 똑같이 AppBar를 하나 만들어 보겠습니다. 

class BaseAppBar extends StatelessWidget {

  const BaseAppBar({Key key,
    @required this.title,
    this.center = false})
      : super(key: key);

  final String title;
  final bool center;

  @override
  Widget build(BuildContext context) {
    return AppBar(
      leading: IconButton(
        icon: Image.asset("assets/images/ic_chevron_30_back.png", width: 24, height: 24,),
        onPressed: () => Navigator.of(context).pop(),
      ),
      centerTitle: center,
      title: Text("$title", style: TextStyle(color: Colors.black, fontSize: 18.0, fontWeight: FontWeight.w700),),
    );
  }
}

 

여기서 간단하게 AppBar에 사용된 속성들을 보면 

leading 은 AppBar 왼쪽에 위치하는 위젯이고,

centerTitle은 bool값으로 ture면 센터정렬, false면 기본 정렬입니다.

title은 AppBar에 들어갈 제목입니다.

 

현재는 title값을 필수로 받게 해두었고, centerTitle을 제어할 값은 기본값을 false로 해두었습니다.

 

아마도 아래와 같이 나올 것으로 기대하고있습니다. 

 

이제 공통으로 만들었으니,

필요한 곳에 마구마구(?) 넣어보겠습니다. 

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: BaseAppBar(title: "알림 리스트", center: false,),

자 끝났습니다.!

이걸 왜 포스팅 한거죠~ 빌드만 하고 끝낼께요.

 

오늘도 역시 레드 스크린이...

 

The getter 'preferredSize' was called on null.
Receiver: null
Tried calling: preferredSize

 

에러가 발생하네요. 

 

에러의 내용은 즉슨. AppBar의 높이에 대한 정보가 없어서 발생했다 정도로 생각하면 되겠습니다.

 

해결책은 BaseAppBar를 만든곳에 

class BaseAppBar extends StatelessWidget implements PreferredSizeWidget {
@override
Size get preferredSize => Size.fromHeight(appBar.preferredSize.height);

추가해주시고, BaseAppBar에 AppBar를 넘겨받아줍니다.

 

Full Source입니다.

 

class BaseAppBar extends StatelessWidget implements PreferredSizeWidget {

  const BaseAppBar({Key key,
    @required this.appBar,
    @required this.title,
    this.center = false})
      : super(key: key);

  final AppBar appBar;
  final String title;
  final bool center;

  @override
  Widget build(BuildContext context) {
    return AppBar(
      leading: IconButton(
        icon: Image.asset("assets/images/ic_chevron_30_back.png", width: 24, height: 24,),
        onPressed: () => Navigator.of(context).pop(),
      ),
      centerTitle: center,
      title: Text("$title", style: TextStyle(color: Colors.black, fontSize: 18.0, fontWeight: FontWeight.w700),),
    );
  }

  @override
  Size get preferredSize => Size.fromHeight(appBar.preferredSize.height);
}

호출하는 부분에서는 

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: BaseAppBar(appBar: AppBar(), title: "알림 리스트", center: false,),

요렇게 호출해주시면 됩니다.

 

이제 이걸 기본으로 여러가지 옵션들을 추가해주시면 더 풍성하고 효율적인 AppBar를 만들 수 있습니다.

 

오늘 포스팅은 여기까지 하겠습니다.

즐코하세요!

 

 

반응형