ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Flutter 기본 위젯, 레이아웃 설정 방법
    Flutter 2023. 7. 26. 20:27
    728x90
    반응형
    SMALL

    오늘은 Flutter 프로젝트를 새로 만들 때 생성되는 기본 구조와 기본 위젯, 레이아웃 잡는 법에 대해 살펴보도록 하겠습니다.

     

    프로젝트 구조

    프로젝트 구조
    프로젝트 구조

    android, ios, web 디렉토리 : android, ios, web에 필요한 기능들이 들어 있습니다.

    lib : 플러터 다트 소스 파일들을 담는 디렉토리입니다. 프로젝트 시작하면 main.dart파일이 생성되어 있습니다.

    test : 테스트 소스 코드를 위한 디렉토리입니다.

    pubspec.yaml :  앱 이름, 의존성, 환경 변수, 이미지 경로 등 기본 정보들을 담고 있는 파일입니다.

     

    main.dart & main, runApp

    main.dart 파일은 플러터 앱의 시작점이 되는 파일입니다. 어플리케이션 구동 시 맨 처음 호출됩니다.

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

    main과 runApp은 플러터에서 지정한 내장 함수입니다. (runApp의 경우 flutter 소스코드 중 binding.dart에 정의되어 있습니다.)

    위 함수들을 통해 UI로 보여줄 위젯을 넣어 구동시켜 줍니다.

    runApp은 프로젝트 실행 시 단 한 번만 호출됩니다.

     

     

    위젯

    플러터 앱의 UI 구조는 위젯으로 이루어져 있습니다. 여러 개의 위젯을 통해 한 화면을 만들어줍니다.

    import 'package:flutter/material.dart';
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Text('안녕')
        );
      }
    }

    material.dart 패키지는 메터리얼 디자인 위젯을 포함하고 있습니다.

    MyApp이 상속 받고 있는 StatelessWidget은 상태가 없는 위젯입니다. 한 번 그려지고 변경되지 않는 UI의 경우 사용됩니다.

    상태가 있는 위젯은 StatefulWidget으로 위젯의 생명주기 동안 값이 변할 수 있는 위젯입니다.

    실제 UI 구현부는 마지막 return 다음의 MaterialApp() 내용입니다. MaterialApp() 내부에 만들고 싶은 UI를 작성하면 된다는 것을 알고 있으면 됩니다!

     

    MaterialApp은 Material design의 기본적인 골격을 잡아주는 위젯입니다. 다만 구글 스타일의 위젯들이 생성되므로 조금 커스터마이징해서 사용하면 될 것으로 보입니다.

     

    기본 위젯

    기본 위젯으로는 텍스트, 아이콘, 사진, 박스 위젯이 있습니다.

    텍스트, 아이콘, 사진 위젯은 기본적인 요소들을 나타내줍니다.

    Text('hihi'), // 텍스트
    Icon(Icons.star), // 아이콘
    Image.asset('assets/image.jpeg'), // 이미지
    Container(width: 40,height: 40,color:Colors.red), // 박스
    SizedBox(width: 40,height: 40, child: Text('hihi')) // 박스

    텍스트 위젯의 경우 Text()로 문자를 감싸주기만 하면 됩니다.

    아이콘 위젯은 Icon()으로 아이콘을 감싸주면 됩니다. 아이콘 라이브러리는 Material Icon(android)와 Cupertino Icon(ios)이 있습니다. 각각 구글에 검색할 경우 사용 할 수 있는 아이콘 종류를 찾아 볼 수 있습니다.

    Material Icons
    Material Icons

    이미지 위젯은 Image.assets() 내부에 이미지 파일 경로를 써주면 됩니다.

    이 때, pubspec.yaml 파일에서 이미지 파일 경로를 추가해줘야 합니다.

    assets/폴더 내부에 이미지를 저장한다면 flutter 속성에 다음을 추가해줘야 합니다.

    flutter:
      assets:
        - assets/

    박스 위젯은 Container와 SizedBox가 있습니다. 가장 큰 차이는 Container에서는 정의할 수 있는 속성이 훨씬 많습니다.

    Container 내부에서 자동완성 단축키를 눌러보면 SizedBox보다 정의할 수 있는 속성이 훨씬 많습니다.

    Container, SizedBox 속성Container, SizedBox 속성
    Container, SizedBox 속성

    또한, Container의 경우 크기 설정을 해주지 않으면 확장 될 수 있는 크기만큼 확장이 되지만, SizedBox는 크기 설정을 해주지 않으면 child의 크기만큼만 설정이 됩니다.

     

    Flutter의 사이즈 단위는 Logical Pixel(LP)로 1cm == 38LP 라고 합니다.

     

     

     

    레이아웃

    Scaffold

    flutter docs에서 살펴본 Scaffold 클래스의 정의는 다음과 같습니다.

    Implements the basic Material Design visual layout structure

    Scaffold는 기본적인 메터리얼 디자인 레이아웃을 제공해줍니다. Scaffold를 통해 상 중 하로 나누어진 레이아웃을 쉽게 사용 할 수 있습니다.

     

    내부적으로 appBar, body, FAB, bottomNavigationBar 등이 있습니다.

    return MaterialApp(
        home: Scaffold(
            appBar: AppBar(title:Text("app bar")),
            body: Text('body'),
            bottomNavigationBar: BottomAppBar(
                child:Text("bottom")
            ),
            floatingActionButton: IconButton(icon: Icon(Icons.star),onPressed: (){},),
          )
        );

    appBar : 어플리케이션의 최상단으로 AppBar를 통해 생성됩니다.

    body : 어플리케이션의 본문으로 여러 위젯들을 넣으면 될 것으로 보입니다.

    FAB : (Floating Action Button) 항상 표시되는 버튼입니다.

    bottomNavigationBar : 어플리케이션 하단으로 네비게이션 바 역할을 할 것으로 보입니다.

    Scaffold 예제
    Scaffold 예제

     

    + 추가

    AppBarleading을 통해 가장 왼쪽에 아이콘을 넣을 수 있습니다. 앱 서랍과 같은 버튼을 넣을 때 사용됩니다.

    actions을 통해 가장 오른족에 아이콘을 넣을 수 있습니다. 리스트 형태로도 넣을 수 있습니다.

    appBar: AppBar(
        leading: Icon(Icons.list),
        title:Text("app bar"),
        actions: [
            Icon(Icons.star),
            Icon(Icons.sunny),
            Icon(Icons.cloud),
        ],
    ),

    app bar 추가 예제
    app bar 추가 예제

     

    가로 세로 배치

    Row, Column 위젯을 통해 여러 위젯들을 가로로, 세로로 배치 할 수 있습니다.

    // 가로
    body: Row(
        children: [
            Container(width:50,height:50,color:Colors.blue),
            Container(width:50,height:50,color:Colors.red),
            Container(width:50,height:50,color:Colors.purple),
            Container(width:50,height:50,color:Colors.black),
        ],
    ),
    
    // 세로
    body: Column(
        children: [
            Container(width:50,height:50,color:Colors.blue),
            Container(width:50,height:50,color:Colors.red),
            Container(width:50,height:50,color:Colors.purple),
            Container(width:50,height:50,color:Colors.black),
        ],
    ),

    Row, Column 예시Row, Column 예시
    Row, Column 예시

    mainAxisAlignment, crossAxisAlignment 속성을 통해 기본 정렬 기능들을 사용 할 수 있습니다.

    mainAxisAlignment은 현재 기준이 되는 축에 대한 설정을 해줍니다.

    crossAxisAlignment는 기준의 반대 되는 축에 대한 설정을 해줍니다.

    body: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
            Container(width:50,height:50,color:Colors.blue),
            Container(width:50,height:50,color:Colors.red),
            Container(width:50,height:50,color:Colors.purple),
            Container(width:50,height:50,color:Colors.black),
        ],
    ),

    mainAxisAlignment 예시
    mainAxisAlignment 예시

    기존에 css 속성 중 하나인 flex와 사용법이 굉장히 비슷하다고 느껴졌습니다.

     

     

    여백 넣는 방법

    padding, margin 속성을 통해 위젯 내부, 위젯 간의 여백을 생성 할 수 있습니다.

    // 상, 하, 좌, 우 한 번에 설정
    Container(width:50,height:50,color:Colors.blue,padding: EdgeInsets.all(10),
        child:Text("padding")
    ),
    
    //상, 하, 좌, 우 따로따로 설정
    Container(width:50,height:50,color:Colors.blue,padding: EdgeInsets.fromLTRB(10, 0, 0, 0)
        child:Text("padding")
    ),

    padding과 maring의 경우 EdgeInsets클래스를 통해 값을 줄 수 있습니다.

    padding 예시padding 예시padding 예시
    padding 예시

     

     

    style 적용

    decoration 속성을 통해 테두리와 같은 스타일 요소들을 적용시킬 수 있습니다.

    Container(
        width:50,height:50,
        decoration: BoxDecoration(
            border: Border.all(color: Colors.black),
        ),
    ),

     

     

    정렬 배치

    Center 위젯과, Align 위젯을 통해 원하는 위치에 배치할 수 있습니다.

    Center(
        child: Container(),
    ),
    
    Align(
        alignment: Alignment.centerLeft,
        child: Container(),
    ),

    Center 위젯은 child 위젯을 화면 정중앙에 배치해줍니다.

    Align 위젯은 alignment 속성을 통해 원하는 위치에 배치시켜줍니다.

     

     

    버튼

    버튼은 TextButton(), IconButton(), OutlinedButton(), ElavatedButton() 등이 있습니다.

    각각 child(IconButton은 icon) 와 onPressed가 정의되어 있어야 합니다.

    style 속성과 ButtonStyle() 위젯을 통해 스타일해줄 수 있습니다.

    Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
            TextButton(child: Text('TextButton'),onPressed: (){},),
            IconButton(icon: Icon(Icons.star),onPressed: (){},),
            OutlinedButton( child: Text('OutlinedButton'),onPressed: (){}),
            ElevatedButton( child: Text('ElevatedButton'),onPressed: (){})
        ],
    ),

    버튼 예시
    버튼 예시

     

    커스텀 위젯

    code 입력 창에 stless를 입력하면 새로운 stateless widget이 생성됩니다.

    클래스 명을 입력하고, return문에 레이아웃을 작성해주면 됩니다.

    커스텀 위젯은 정의된 위젯 중 하나를 상속 받고, 어떤 파라미터를 받을 지 정의해주고, build 메소드를 재정의해주면 됩니다.

    class MyApp extends StatelessWidget {
      ...
      body: NewWidget(),
      ...
    }
    
    class NewWidget extends StatelessWidget {
      const NewWidget({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Text("This is New Widget");
      }
    }

    커스텀 위젯
    커스텀 위젯

     

     

     

    정리

    오늘은 플러터 기본 위젯과 레이아웃을 잡는 방법에 대해 배워보았습니다.

    생각보다 많이 직관적인 기본 함수들로 인해 빠르게 배울 수 있었던 것 같습니다. 레이아웃과 같은 경우도 css의 flex와 유사하여 빠르게 습득 할 수 있었습니다. 커스텀 위젯과 같은 경우 새로운 컴포넌트를 작성하듯이 쓰면 될 것 같다고 생각했습니다.

    이제 다음 포스팅부터 dart 언어, 소스코드의 파일 구조라던가 비동기 작업을 어떻게 하는지 위주로 빠르게 살펴보도록 하겠습니다.

    반응형
    LIST

    댓글

Designed by Tistory.