본문 바로가기
Frameworks & Libraries/Flutter

Flutter Widget API - 1 - 제일 큰 틀 살펴보기

by 리나그(ReenAG) 2021. 12. 25.
728x90
반응형

 이번에 자율동아리를 따로 진행하면서 해야 할 일도 많아지고... 했는데, 그중에 하나가 flutter 겨울 프로젝트이다. 같은 동기들끼리 진행하게 되었는데, 종강을 질질 끌어서 어제 하는 바람에 코딩 셰프가 만든 강의를 들여다본다는 게 늦어진 데다 펑크까지 내버렸다. 그래서 어떻게 든 빠르고 정확하게 이 실수를 만회해야 한다. 내가 제일 (생각 없이) 잘하는 건 글을 끄적이는 것이기 때문에 이걸 이용해서 배운걸 한번 빠르게 정리해보고자 한다.

 

 Flutter는 앱을 만들 수 있는 일종의 Framework이다. 놀라운 것은 이 프레임워크하나로 안드로이드에서도, IOS에서도, Chrome에서도 돌아갈 앱을 만들 수 있다.(물론 최적화 이슈는 있겠지만..) 코셰 님의 말에 따르면 나중에 구글이 만들 OS의 안배라고 하던데... 중요한 것은 듣도 보도 못한 Dart라는 언어를 사용하는 것이다. 느낌은... c++인데, 메서드나 namedargument같은 문법은 ruby나 python, void main()으로 닥치고 시작하는 느낌은 c를 닮아서, 이리저리 짬뽕된 느낌이다. 내가 아는 언어의 세계가 뒤지게 좁다는 걸 체감한 뒤라서 별 거부감은 없었다.

 

아무튼 이론은 대강 이렇고, Flutter App의 구조 자체는 tree형식으로 크게 복잡하지는 않다. 단지 무지막지하게 복잡하게 만들 수 있고 메서드도 많을 뿐...

시작 코드는 대강 이렇다 :

import 'package:flutter/material.dart';
import 'profile.dart';

void main() => runApp(MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'It\'s over anakin',
      theme: ThemeData(
        primarySwatch: Colors.blue
      ),
      home: const Profile(),
      //home: MyHomePage(),
    );
  }
}

main이 runApp을 호출하고, StatelessWidget인 MyApp()이 리턴된다. 여기서 재미있는 것은 build함수 내부에 "위젯"이라 불리는 UI단위들을 rescursive하게 넣어서 갖가지 기능을 구현할 수 있다.

 

일반적으로 Flutter의 Dart에 대한 기본적인 컨벤션은 :

class 이름은 첫자 포함 낙타체

변수 이름 / namedArgument 이름은 첫차 제외 낙타체

1. MaterialApp

앱의 최상단에 위치하는 거대한 껍데기.

(1).debugShowCheckedModeBanner : bool

오른쪽 위에 위치한 빨간색 Demo표식을 지우고 싶으면 false

(2).home : Widget

여타 다른 Widget의 child와 비슷하나, 여기서 부터 진짜로 drawing이 되는 속성이 부여되는 듯싶다.

(3).theme : ThemeData

앱의 전체적인 theme을 만들 수 있는 것 같다. 저 위의 예제에서는 primarySwatch 정도만 부여했다.

 

2. Scaffold

처음에 이 낱말을 보자마자 든 생각은 :

이거?

아무튼 앱의 제일 큰 뼈대이다. 처음에 body만 생각하면 대수롭지 않게 생각할지도 모르겠지만, 상단의 appbar / 좌단의 drawer / 중앙의 body로 큼직큼직한 구획을 나누는 역할을 맡는, 말 그대로 스케폴딩 같은 역할일지도 모르겠다.

(1).backgroundColor : Color

(2).appbar : Appbar

상단 AppBar, 따로 Class도 있으니 쓰자.

(3).drawer : Drawer

좌단 Drawer, 마찬가지로 따로 Class도 있으니 쓰자.

(4).body : Widget

얘는 예외, Padding도 좋고 Center도 좋고... 일단 말이 되는 위젯이면 된다.

 

3. AppBar

앱의 상단에 위치하는, 어째서인지 있으면 구려 보일 때가 많은, 그 UI이다.

(1).backgroundColor : Color

(2).centerTitle : bool

false일시 좌측 정렬

(3).elevation : float

AppBar의 아래에 비칠 그림자 크기. 아래쪽이 아니라 아예 AppBar 아래의 여백에 그림자가 생긴다. 0이면 그림자가 생기지 않는다.

(4).actions : <Widget>[]

AppBar 오른쪽에 아이콘을 여러 개 추가할 수 있다.

(5).leading : Widget

AppBar 왼쪽에 아이콘을 한 추가할 수 있다.

 

예제 :

AppBar(
        title: const Text("Profile"),
        backgroundColor: Colors.blue[700],
        centerTitle: true,
        elevation: 0.0,
        actions: <Widget>[
          Builder(builder: (context) => 
            IconButton(
              icon: Icon(Icons.menu),
              onPressed: () => Scaffold.of(context).openDrawer(),
        ))],
        leading: IconButton(
          icon: Icon(Icons.access_alarm_outlined),
          onPressed: () {},
        ),
      )

 

4. Drawer

앱의 왼쪽에서 보이지 않다가 튀어나오는 그 UI. 오른쪽 버전도 있을 것 같다.

(1).child : Widget

AppBar랑은 다르게 이 녀석은 크게 특징이... 없다? API를 찾아보면 또 있겠지만 (예를 들어 튀어나오는 속도라던가)

암튼 직접 이렇게 ListView로 구현해주어야한다.

예제 :

	Drawer(
        child: ListView(
          padding: EdgeInsets.zero,
          children: <Widget>[
            UserAccountsDrawerHeader(
              currentAccountPicture: CircleAvatar(
                backgroundImage: AssetImage('assets/github_bruh.png'),
              ),
              accountEmail: Text('Yee@naver.com'),
              accountName: Text('WhatThe...'),
              onDetailsPressed: () {
                print("Arrow");
              },
              decoration: BoxDecoration(
                color: Colors.amber[800],
                borderRadius: BorderRadius.only(
                  bottomLeft: Radius.circular(40.0),
                  bottomRight: Radius.circular(40.0)
                )
              ),
            ),
            ListTile(
              leading: Icon(Icons.home),
              title: Text('Home'),
              tileColor: Colors.grey[300],
              onTap: () {
                
              },
            ),
            ListTile(
              leading: Icon(Icons.settings),
              title: Text('Settings'),
              tileColor: Colors.grey[300],
              onTap: () {

              },
            ),
            ListTile(
              leading: Icon(Icons.chat),
              title: Text('Q&A'),
              tileColor: Colors.grey[300],
              onTap: (){

              },
            )
          ],
        ),
      ),

 

암튼 복습은 오늘은 여기까지! 진도도 나가야하니까. 어떤 모 책에 의하면, 일단 동기부여를 하는 첫 번째는 죄다 쪼개는 거라고 한다. 그러니까 글도 쪼갤거다.

728x90
반응형