티스토리 뷰

반응형

모바일 앱을 보면 상중하로 나뉘어져 있는 경우가 많다. 아무래도 모바일은 화면이 작기 때문에 윈도우에서 처럼 많은 UI를 한 화면에 담을 수가 없어서 상중하로 나누면 작은 화면을 효율적으로 사용할 수 있다. 정해진건 아니지만 보통 상단과 하단은 고정 UI를 넣어서 다른 메뉴로 이동하거나 이벤트를 바로 실행하는 기능을 넣고 중간 부분은 내용을 보여주는 경우가 많은 것 같다.

 

 

 


 

네이버 모바일 layout

 

flutter의 경우 상중하를 Scaffold 위젯을 사용해서 간편하게 나눌 수 있다. 우선 결과물부터 보면 아래 이미지와 같다. 상단에 appbar를 위치시켰고 중간과 하단에는 배경색을 넣어서 구분만 해놨다. 실제로 앱을 만든다면 중간에는 내용이 들어가고 하단에는 navigation 같은게 들어가면 좋을 것 같다.

 

 

 


 

flutter에서 Scaffold 위젯으로 상중하 구분

 

 

 


 

전체 소스코드


import 'package:flutter/material.dart';

void main() {
  runApp(const App());
}

class App extends StatelessWidget {
  const App({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {

    return MaterialApp(
        home: Scaffold( // appbar, body, bottom 으로 상중하 구분 가능
          appBar: AppBar( // 상단 bar
            leading: Icon(Icons.menu),
            title: Text('PrintApp'),
            backgroundColor: Color.fromRGBO(30, 100, 120, 1), // bar 배경색
            actions: [
              Container(
                margin: EdgeInsets.fromLTRB(0, 0, 10, 0),
                child: Icon(Icons.add), // add icon
              )
            ],
          ),
          body: Container( // 중간 내용
            color: Colors.blue, // 배경색
            child: Center(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center, // 가로 중간 정렬
                children: [
                  Text('중간', style: TextStyle(color: Colors.white)),
                ],
              ),
            )
          ),
          bottomSheet: Container( // 하단 sheet
            color: Colors.red, // 배경색
            height: 50,
            margin: EdgeInsets.fromLTRB(0, 0, 0, 10),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center, // 가로 중간 정렬
              children: [
                Text('하단', style: TextStyle(color: Colors.white),)
              ],
            ),
          ),
        )
    );
  }
}

 

 

 


 

상단 appBar 부분

 

Scaffold를 설명하기에 앞서 flutter에서 제공하는 UI 템플릿에 대해서 간단히 설명이 필요할 것 같다.

일단 return MaterialApp 괄호 안에 들어있는 위젯들도 실제 flutter 화면을 구성하게 된다. MaterialApp은 flutter에서 제공하는 UI 템플릿이고 그안에 많은 기능들과 위젯들이 들어있다. 만들어진 객체들을 편하게 가져다 쓸 수 있도록 도와주기 때문에 정말 모든 부분을 custom해서 사용할게 아니면 MaterialApp을 사용하는 게 생산성에 좋다. 그리고 CupertinoApp도 있는데 서로 기능들은 유사하지만 Material과 Cupertino 간에 UI가 조금 다르다. 흔히들 Material은 구글과 비슷하고 Cuptertino는 애플과 조금 더 비슷하다고 생각하면 된다. UI 템플릿 부분은 추후 따로 작성하도록 하겠다.

 

home: Scaffold 위젯을 넣어서 화면 전체를 Scaffold로 감싼다. 그 이후에 상단에서 사용할 appBar 위젯을 넣어서 앱에서 사용할 상단바를 추가했다. 그리고 appBar에 아래 속성을 넣어서 상단바를 구성했다.

 

leading : 왼쪽 아이콘

title : 제목

actions : 우측에 이벤트로 사용할 Icon을 넣었다. Icons.add 아이콘이 너무 우측에 달라 붙어서 우측 마진을 10을 줬다.

 

return MaterialApp(
    home: Scaffold( // appbar, body, bottom 으로 상중하 구분 가능
      appBar: AppBar( // 상단 bar
        leading: Icon(Icons.menu),
        title: Text('PrintApp'),
        backgroundColor: Color.fromRGBO(30, 100, 120, 1), // bar 배경색
        actions: [
          Container(
            margin: EdgeInsets.fromLTRB(0, 0, 10, 0),
            child: Icon(Icons.add), // add icon
          )
        ],
      ),

 

 

 


 

중간 body 부분

 

body 부분은 Container로 감싼 후 배경색을 칠하고 "중간" 이라는 글자를 넣어줬다. flutter에서 위젯 하위에 위젯이 들어갈 경우 단수면 child, 복수면 children을 사용해서 넣을 수 있는데 모든 위젯에 child, children을 넣을 수 있는 건 아니고 위젯마다 다르다. Container의 경우 child를 넣을 수 있고 Row의 경우 children을 넣을 수 있다. 그리고 Row 위젯에 입력한 "mainAxisAlignment: MainAxisAlignment.center"  옵션은 가운데 정렬을 시키는 옵션이다.

 

 

  body: Container( // 중간 내용
    color: Colors.blue, // 배경색
    child: Center(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center, // 가로 중간 정렬
        children: [
          Text('중간', style: TextStyle(color: Colors.white)),
        ],
      ),
    )
  ),

 

 

 


 

하단 bottomSheet 부분

 

bottom에 들어간 옵션들은 대부분 위에서 설명했고 margin은 처음보는 옵션이다. margin의 경우 상하좌우에 여백을 주는 옵션인데 이미지나 폰트가 화면 너무 끝에 붙어있으면 답답해 보일 수 있는데 그럴 경우 margin을 줘서 디자인을 해주면 좋다. 이번 샘플의 경우도 bottomSheet를 사용하면 화면 최하단에 "하단" 글자가 들어가서 bottom margin을 줘서 조금 위로 올렸다.  fromLTRB 파라미터 순서에 맞게 숫자를 넣어주면 마진이 설정된다.

margin : EdgeInsets.fromLTRB(left, top, right, bottom)

  bottomSheet: Container( // 하단 sheet
    color: Colors.red, // 배경색
    height: 50,
    margin: EdgeInsets.fromLTRB(0, 0, 0, 10),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.center, // 가로 중간 정렬
      children: [
        Text('하단', style: TextStyle(color: Colors.white),)
      ],
    ),
  ),
)

 

반응형
댓글
공지사항