본문 바로가기

Frontend/Flutter

[Flutter] 코딩애플 : 쉬운 플러터 1-6강

1강 : 기본 위젯 4개 알면 기초 끝

 

1. lib폴더 안의 main.dart 기본 구조

import 'package:flutter/material.dart';	// 이건 그냥 라이브러리 가져오는 거~

void main() {
  runApp(const MyApp());	// 앱 시작해주세요~
}

// 'stless' 입력 후 TAB 키 눌러서 자동 생성하자
class MyApp extends StatelessWidget {
  const MyApp ({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
  
  return MaterialApp(
  	// 코딩(앱디자인)은 여기서부터 시작!
  );
  }
}

StatelessWidget 안에 MyApp만 추가해주면 기본 뼈대 완성

 

 

2. 기본 위젯 4개 : 글자, 이미지, 아이콘, 박스

(1) Text('글자')

 

(2) Image.asset('경로')

     - 이미지 폴더 만들고

     - 이미지 등록하고 : test/pubspec.yaml 파일에다가 아래와 같이 적기

flutter:
  // 요 아래 부분 적기
  assets:
    - assets/

     - 경로 설정해주기

 

(3) Icon(Icons.아이콘이름) 

     - 아이콘 이름은 Flutter 홈페이지에서 가져다 쓰기

 

(4) Container() 또는 SizedBox()

     - 이 친구들은 child를 가질 수 있음

     - 스타일 줄 때는 (스타일명 : 값)      ex. width, height, color 등

 

 

 

 

 

 

2강 : 가로세로 배치하는 법과 Scaffold

 

1. 머리 가슴 몸통 : Scaffold()로 나누자!

home: Scaffold(
  appBar: AppBar(),	// 머리
  body: Cotainer(),	// 가슴
  bottomNavigationBar: BottomAppBar(),	// 몸통
  )

 

2. 가로 세로 배치

     (1) 가로로 하나만 배치 : Container( child: 위젯 )

home: Scaffold(
  body: Container(
    child: Icon(Icons.star)
    ),	// Container
  )	// Scaffold

     

     (2) 가로로 여러개 배치 : Row( children: [ 위젯 여러개 ] )

home: Scaffold(
  body: Row(
    bhildren: [
      Icon(Icons.star),
      Icon(Icons.circle),
      Icon(Icons.square),
      ],
    ),	// Row
  )	// Scaffold

* Icon 린트 없애려면 test/analysis_options.yaml 에다가 prefer_const_literals_to_create_immutables : false 추가하기

 

     (3) 세로로 배치 : Row 말고 Column 써라

 

     (4) 가운데 정렬 : Row() 안에다가

          - 가로축 정렬 :mainAxisAligment: MainAxisAlignment.center 추가하기

          - 세로축 정렬 : crossAxisAlignment : CrossAxisAlignment.center 추가하

 

          ->  자동완성으로 다른 기능들 써보면,,, CSS의 display : flex와 매우 유사

          ->  Column에서 세로정렬은..? : 빡대가리들은 생각금지, ctrl + space 누르셈

 

 

     Q. 파라미터 우측에 뭐 넣을지 까먹음

     A. 1) 왼쪽에 있는 걸 대문자로 써보든가

          2) 파라미터에 마우스 올려보든가 -> Type에 나오는 걸로 쳐보든가

          3) 당연히 검색해봐야

 

 

3. 숙제 인증샷

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());  // 앱 시작해주세요~
}

// stless 입력 후 tab 키 누르면 자동 생성 : StatelessWidget
// 아래 네 줄 채우면 메인페이지 세팅 끝!
class MyApp extends StatelessWidget {
  const MyApp ({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {

    // 코딩은 요 아래서부터 시작
    return MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: Text('앱임'),
          ),
          body: Container(
            child: Text('안녕'),
          ),
          bottomNavigationBar: BottomAppBar(
            child: Container(
              height: 60,
              child : Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  Icon(Icons.phone),
                  Icon(Icons.message),
                  Icon(Icons.contact_page),
                ],
              )
            )
          ),
        )
      );
  }
}

 

* 숙제하다가 구글링 한 것

- 하단바 높이 설정하기

   : Row()를 Container()로 감싸주고 Container에다가 height 속성값을 정해줬다.

 

* 꿀 Tip

- 노란 전구의 존재  

   : Row()를 Container()로 싸맬 때, Row()에다가 마우스 커서 갔다 대면 왼쪽에 노란 전구 눌러보셈.

     Wrap with ~ 엄청 많음... 유레카..!

 

- Container() vs SizedBox()

   : width, hieght, child만 필요한 박스는 SizedBox() 쓰기

     vs

     Cotainer()는 꽤 무거

 

 

 

 

 

3강 : 박스 잘 그려야 앱 잘 만듭니다

 

1. 박스 디자인 : margin, padding, border

- 모든 UI의 기원은 네모박스 : Container()

 

   (1)  margin : 바깥 여백

body: Container(
   width: 150, height: 50, color: Colors.blue,
   margin: EdgeInsets.all(20)	// 전부 여백
   margin: EdgeInsets.fromLTRB(left, top, right, bottom)	// 개별 여백

   (2) padding: 안쪽 여백

     : margin이랑 사용법은 똑같음

 

   (3) 나머지 찌끄레기 박스 스타일 : decoration 안에 넣기

body: Container(
   width: 150, hieght: 50,
   decoration: BoxDecoration(
      // 여기다가 찌끄래기 다 넣기~
      color : Colors.blue	// BoxDecoration 넣으면 Cotainer 색상은 요 안에다가 정의해주기
      border: Border.all(color: Colors.black)
      
   )
)

   * 박스 width를 가로로 꽉차게?

        -> width: double.infinity

 

 

2. 박스 위치 정렬

   (1) 가운데 정렬 : Center()로 박스 감싸기

   (2) 아무 정렬 : Align()으로 박스 감싸기 & 파라미터로 alignment: Alignment.요소 넣기

 

 

 

 

 

4강 : AppBar(아빠)

 

1. 글자와 아이콘 스타일

   (1) 글자 디자인하는 법(Typography)

         Text() 안에다가 파라미터로 style: TextStyle( 여기에다가 여러 가지 속성 넣기 )

 

         *** 속성은 필요할 때 찾아 써야함. (어차피 다음날 다 까먹음)

         *** fontWeight는 좀 자주 쓰는 속성임. 글자 두께 

 

   (2) 아이콘 디자인하는 법

         마찬가지임. Icon() 안에다가 파라미터로 color, size(가 끝임) 디자인 할 수 있음

 

   (3) 버튼 디자인하는 법

         TextButton()

         IconButton()

         ElevatedButton() -> 색깔 채워진 버튼, 누르면 물결 퍼지는 효과도 디폴트

         버튼 넣고 싶을 때 택1

 

         => 버튼엔 필히 'child: 자식요소, onPressed: (){} ' 파라미터 넣어야 잘보임.

         => 버튼도 스타일 주려면 파라미터로 style: ButtonStle( 여기에다 속성 넣기 )

 

 

2. AppBar 디자인은

   (1) AppBar() 안에 넣을 수 있는 것들

      - title: 왼쪽제목

      - leading: 왼쪽에 넣을 아이콘

      - actions: [우측 아이콘들 : 리스트라서 여러 개 입력 가능 ]

 

 

 

3. 레이아웃 혼자서도 알아서 잘 짜려면

   (1) 예시디자인 준비 ( 없으면 다른 앱 베껴야 )

   (2) 예시화면에 네모 그리기 : 빈 공간 없게 네모 그려보기

   (3) 바깥 네모부터 하나 하나 위젯으로

   (4) 마무리 디자인

 

 

4. 숙제

목표 디자인 & 힌트

 

완성..!!!!!!!!!!!!

 

진짜 chat GPT 없었으면 못 했다..

영상에서 안 배운 부분이 더 많기도 하고 눈에 자꾸 보이니까 디자인 더 비슷하게 할라고 계속 구글링했다.

요 정도면 성공..ㅇㅈ?

 

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());  // 앱 시작해주세요~
}

// stless 입력 후 tab 키 누르면 자동 생성 : StatelessWidget
// 아래 네 줄 채우면 메인페이지 세팅 끝!
class MyApp extends StatelessWidget {
  const MyApp ({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {

    // 코딩은 요 아래서부터 시작
    return MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: Row(
              children: [
                Text(
                    '금호동3가',
                    style: TextStyle(
                      color: Colors.black,
                      fontWeight: FontWeight.w700,
                    ),
                ),
                IconButton(
                  icon: Icon(
                    Icons.arrow_downward,
                    color: Colors.black,
                    size: 20.0,
                  ),
                  onPressed: () {
                    print('Arrow_downward button clicked!');
                  },
                )
              ],
            ),
            backgroundColor: Colors.white,
            actions: [
              IconButton(
                  icon: Icon(
                      Icons.search,
                      color: Colors.black,
                  ),
                  onPressed: () {
                    print('Search button clicked!');
                  }
                  ),
              IconButton(
                  icon: Icon(
                      Icons.menu,
                      color: Colors.black,
                  ),
                  onPressed: () {
                    print('Menu button clicked!');
                  }
              ),
              IconButton(
                  icon: Icon(
                      Icons.notifications,
                      color: Colors.black,
                  ),
                  onPressed: () {
                    print('Alarm button clicked!');
                  }
              ),
            ],
          ),
          body: Container(
            height: 175,
            width: double.infinity,
            padding: EdgeInsets.all(10),
            child: Row(
              children: [
                Image.asset('guard_cells.jpg'),
                Expanded(
                  child: Container(
                    margin: EdgeInsets.fromLTRB(5, 0, 0, 0),
                    padding: EdgeInsets.all(10),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Container(
                          child: Text(
                            '캐논 DSLR 100D (단렌즈, 충전기 16기가SD 포함)',
                            style: TextStyle(
                              fontSize: 18.5,
                            ),
                          ),
                        ),
                        SizedBox(
                          height: 5,
                        ),
                        Container(
                          child: Text(
                            '성동구 행당동·끌올 10분 전',
                            style: TextStyle(
                              fontSize: 12.5,
                              color: Colors.grey,
                            ),
                          ),
                        ),
                        SizedBox(
                          height: 5,
                        ),
                        Text(
                          '210,000원',
                          style: TextStyle(
                            fontSize: 15.0,
                            fontWeight: FontWeight.w800,
                          ),
                        ),
                        SizedBox(
                          height: 5,
                        ),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.end,
                          children: [
                            Icon(Icons.favorite),
                            Text('4'),
                          ],
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          )
        )
    );
  }
}

그냥 이 짤이 떠올랐음

 

 

 

 

5강 : Flexible과 숙제 안해오면 때림

(저기여.. 전 이미 Flexible 엄청 썼는데.. 이걸 이제 알려주시다니..)

 

1. 박스폭을 50%로 설정하려면? ( 상대적 크기 )

Flexible()로 감싸고 flex 파라미터에 배수 관계로 몇 대 몇으로 나눌 건지 적기( ex.삼등분하고 싶으면 1:1:1 )

body: Row(
	children: [
    	Container( width: 100 ),
        Container( width: 200 ),
    ]	// 고정값으로 너비 설정하는 법
)
body: Row(
	children:[
    	Flexible(child: Container(), flex: 3),
        Flexible(child: Container(), flex: 7),
    ],	// 상대적으로 너비 설정하는 법
)

 

2. Row()안에서 박스 하나만 꽉 채우고 싶다면?

-> Expanded() 써라, 다른 container가 쓰고 남은 공간 꽉 채움.

 

 박스 폭을 %로 주고 싶으면 Flexible
 박스 하나 넓게 채우려면 Expanded

 

3. 박스 디자인 했는데 의도와 다르다면

(1) 사이즈가 이상해서 그럼

(2) 박스 위치가 이상해서 그럼

(3) DevTools 눌러보기 -> inspector로 container들 사이즈 볼 수 있음

 

 

 

 

 

 

6강 : 중요한 커스텀 위젯 문법

 

1. 레이아웃용 위젯들이 너무 길다면?

-> 커스텀 위젯으로 깔끔하게 축약가능

-> 재사용 많은 UI들, 큰 페이지들만 사용하기 / 무부별하게 쓰지x

class MyApp extends StatelessWidget {
  const MyApp ({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {

    // 코딩은 요 아래서부터 시작
    return MaterialApp(
        home: Scaffold(
          appBar: AppBar(),
          body: SayHi(),	// 여기가 바로 커스텀위젯!
          bottomNavigationBar: BottomAppBar(),
        )
    );
  }
}

// 빈공간에다가 stless 랑 tab 누르고
// class 이름 작명한다음
// return에다가 긴~ 코드 복붙하기

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

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text('안녕하십니까!'),
    );
  }
}

 

 

2. 앱에 보여줄 항목이 여러 개라면? 

ListView() 사용하자

-> 스크롤 바 생김

-> 스크롤 위치 감시 가능

-> 메모리 절약 기능 있음

body: ListView(
	children: [
    	Text('ㅎㅇ'), Text('ㅎㅇ'), Text('ㅎㅇ'), Text('ㅎㅇ'), Text('ㅎㅇ'),
        Text('ㅎㅇ'), Text('ㅎㅇ'), Text('ㅎㅇ'), Text('ㅎㅇ'), Text('ㅎㅇ'),
        Text('ㅎㅇ'), Text('ㅎㅇ'), Text('ㅎㅇ'), Text('ㅎㅇ'),
    ]	
)

 

 

3. 숙제

숙제 얍얍

 

완성

 

저 아이콘은 똑같은 걸루 못 찾았음..

하단바는 예전에 썼던 거 재사용함

 

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());  // 앱 시작해주세요~
}

// stless 입력 후 tab 키 누르면 자동 생성 : StatelessWidget
// 아래 네 줄 채우면 메인페이지 세팅 끝!
class MyApp extends StatelessWidget {
  const MyApp ({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {

    // 코딩은 요 아래서부터 시작
    return MaterialApp(
        home: Scaffold(
          appBar: AppBar(),
          body: ListView(
            children: [
              Contact(),
              Contact(),
              Contact(),
            ],
          ),
          bottomNavigationBar: BottomAppBar(
            child: Container(
              height: 60,
              child : Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  Icon(Icons.phone),
                  Icon(Icons.message),
                  Icon(Icons.contact_page),
                ],
              )
            )
          ),
        )
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Icon(Icons.person, size: 50,),
        Text('홍길동', style: TextStyle(fontSize: 15),),
      ],
    );
  }
}

 

 

 


유튜브에 있는 무료강의는 다 들었는데

강의가 재밌기도 하고 짧은데 알짜배기만 이해가 쏙쏙 잘 되가지구 유료 강의도 결제해서 듣고 싶음..

근데 좀 비싼 편인듯. 인프런이나 다른 사이트 대비..

암튼 어차피 플러터로 캡스톤 할 거니까 나중에 들을 듯..!

2학기 모바일 앱 개발에서도 플러터 배우기는 하는데 미리 듣지 모!

 

암튼 이상 끝!

 

'Frontend > Flutter' 카테고리의 다른 글

[Flutter] 개발환경 세팅 중 jdk 환경변수 설정 오류  (0) 2023.08.12