728x90

Image.asset 위젯

Image.asset 위젯은 어플 내부에 미리 저장돼있는 이미지를 사용합니다.

  1. 어플에 이미지 저장
  2. pubspec.yaml에 이미지 등록
  3. 사용

1. 어플에 이미지 저장

폴더생성 버튼을 눌러, assets라는 폴더를 만들어줍니다. 그리고, 사용할 이미지(jpg, jpeg, png 등)를 넣어줍니다.

2. pubspec.yaml에 이미지 등록

pubspec.yaml 파일을 열어, 다음과 같이 # 표시(주석)를 지워줍니다.

다음의 예시 이미지들을 지워주고, 이미지이름을 넣어줍니다.

3. Image.asset 위젯 사용

이제 등록한 경로를 넣어주시면됩니다. asset폴더 안에, war.jpeg를 사용하겠다 = asset/war.jpeg

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          elevation: 0,
          backgroundColor: Colors.white,
        ),
        body: Image.asset('asset/war.jpeg'),
      ),
    );
  }
}

Chip 위젯

Chip 위젯을 통해서 필터, 검색어, 선택 가능한 영역을 줄 수 있다. avatar 속성을 넣을 수도 있다.

body: Chip(
  backgroundColor: Colors.green.shade100,
  avatar: CircleAvatar(
      backgroundColor: Colors.green,
      child: Text('박'),
  ),
  label: Text('박현성'),
),

 

Chip을 여러개 만들었는데 오류가 발생했다.

body: Column(
    children: [
       Container(
          height: 40,
          child: ListView(
             scrollDirection: Axis.horizontal,
             children: [
                Chip(
                  backgroundColor: Colors.green.shade100,
                  avatar: CircleAvatar(
	                  backgroundColor: Colors.green,
	                  child: Text('박'),
	                ),
	                label: Text('박현성'),
                ),
                  ... 생략 ...
             ],
          ),
       ),
    ],
),

ListView는 가로(수평적)로 사용했을 때, 부모의 높이를 전부 사용한다. 근데, 부모가 Column위젯일 경우 에러가 나는데, 그 이유는 Column은 계속해서 수직으로 확장하려고 한다. 따라서 Column이 높이가 정해져 있지 않으니, 본인이 정해져 있는 높이가 없어서 그렇다.

Wrap 위젯

Column 위젯의 단점은, 수직으로 계속 넣기 때문인데, 최대 넓이에 도달함과 관계없이 커지기 때문에, 방지턱(오버플로우)가 일어난다. 그렇다면 최대 넓이가 도달하면 자동으로 다음 줄로 넘기고 싶을 때 사용한다.

Wrap위젯은 children 안에 자식들을 넣어주면 된다. spacing 속성값을 통해 자식들 사이 간격을 정한다. runSpacing 속성 값을 통해 줄단위 사이 간격을 정한다.

body: Column(
    children: [
       Container(
          height: 40,
          child: Wrap(
             children: [
                Chip(
                  backgroundColor: Colors.green.shade100,
                  avatar: CircleAvatar(
	                  backgroundColor: Colors.green,
	                  child: Text('박'),
	                ),
	                label: Text('박현성'),
                ),
                  ... 생략 ...
             ],
          ),
       ),
    ],
),

Button 위젯들

onPressed 속성 : 눌러졌을 때, 실행할 함수 () {} : 우리의 코드블록으로서, { 와 } 사이에 코드를 넣어준다.

즉, {와 }의 사이가 곧 코드조각영역이다.

플러터에서 제공하는 공식 버튼은 크게 5가지인데, 그 버튼들은 다음과 같다. 상황에 맞게 바꾸어 사용하면 된다.

FloatingActionButton, TextButton, ElevatedButton, OutlinedButton, IconButton

728x90

'개발 > Flutter' 카테고리의 다른 글

Flutter 다섯 번째 강의 내용  (0) 2022.10.27
Flutter 네 번째 강의 내용  (0) 2022.10.24
Flutter 세 번째 강의 내용  (0) 2022.10.21
Flutter 두 번째 강의 내용  (0) 2022.10.20
Flutter 첫 번째 강의 내용  (0) 2022.10.18
728x90

Container 예쁘게 꾸미기

body: Center(
    child: Container(
      width: 250,
      height: 250,
      color: Colors.grey.shade300,
      child: Center(
	      child: Text('재미있게 가봅시다!!'),
      ),
   ),
),

container에 color 속성을 넣어서 컨테이너의 색상을 표현할 수 있습니다.

Container에 decoration 속성이 있다. decoration은 Container 위젯의 스타일을 꾸며줄 때 사용한다. decoration 속성을 사용하기 위해 다음과 같이 입력합니다.

body: Center(
    child: Container(
      width: 250,
      height: 250,
      color: Colors.grey.shade300,
         decoration: BoxDecoration(),
      child: Center(
         child: Text('재미있게 가봅시다!!'),
      ),
   ),
),

decoration을 사용한 이후부터는, color를 반드시 BoxDecoration 안에 넣어야 한다. color 속성을 옮기어 decoration 값 안에 넣는다.

body: Center(
    child: Container(
      width: 250,
      height: 250,
      decoration: BoxDecoration(
         color: Colors.grey.shade300,	
      ),
      child: Center(
         child: Text('재미있게 가봅시다!!'),
      ),
   ),
),

그리고, BoxDecoration 안에 디자인 속성을 하나하나씩 넣어주면 된다.

border: 테두리 선 추가

all을 사용하여 전체 면에 테두리 설정 가능

body: Center(
    child: Container(
      width: 250,
      height: 250,
      decoration: BoxDecoration(
           color: Colors.grey.shade300,
           border: Border.all(),	
      ),
      child: Center(
           child: Text('재미있게 가봅시다!!'),
      ),
   ),
),

면마다 설정 따로 가능

body: Center(
    child: Container(
      width: 250,
      height: 250,
      decoration: BoxDecoration(
           color: Colors.grey.shade300,
           border: Border(
              bottom: BorderSide(),
              right: BorderSide(),
           ),	
      ),
      child: Center(
          child: Text('재미있게 가봅시다!!'),
      ),
   ),
),

borderRadius: 가장자리 둥글게

body: Center(
    child: Container(
      width: 250,
      height: 250,
      decoration: BoxDecoration(
          color: Colors.grey.shade300,
          borderRadius: BorderRadius.circular(30),	
      ),
      child: Center(
          child: Text('재미있게 가봅시다!!'),
      ),
   ),
),

일반적으로 circular (둥글게), only 가 제일 많이 사용됨

gradient: 색상 그레디언트 넣기

body: Center(
    child: Container(
      width: 250,
      height: 250,
      decoration: BoxDecoration(
          color: Colors.grey.shade300,
          gradient: LinearGradient(
              colors: [
                  Colors.red,
                  Colors.orange,
              ],
          ),
      ),
      child: Center(
          child: Text('재미있게 가봅시다!!'),
      ),
   ),
),

shadow: 그림자 넣기

body: Center(
    child: Container(
      width: 250,
      height: 250,
      decoration: BoxDecoration(
         color: Colors.grey.shade300,
         boxShadow: [
            BoxShadow(
              color: Colors.black26,
              spreadRadius: 4,
              blurRadius: 8,
            ),
         ],
      ),
      child: Center(
         child: Text('재미있게 가봅시다!!'),
      ),
   ),
),
clipBehavior

clipBehavior

container의 기본 clip behavior를 생각하자. 자식은, 부모의 상황을 전부 알지 못한다. 특히, 부모의 모양을 모르기 때문에, Container의 모양에 맞게 범위에 벗어날 경우를 대비하여 자식이 범위 밖을 지나면 자동으로 잘라주는 clipBehavior를 설정할 수 있다.

ListView 더 알기

우리에게 스크롤 기능을 주는 ListView는 수직으로만 사용했는데, 우리가 주는 속성 값에 따라 수평으로도 사용이 가능하다. 기본값의 스크롤 방향이 수직으로 설정돼있던 것이다.

중심, 회전축의 뜻을 가지고 있는 Axis, ListView에는 scrollDirection 속성을 설정할 수 있는데, 요구되는 데이터 타입이 Axis이다.

ListView의 속성 중 scrollDirection의 기본값은 Axis.vertical 이기 때문에 수직 스크롤이 되는 것이다.

Q. 그러면, Axis.vertical만 Axis.horizontal로 바꿔주면 되는 것 아닌가요?

맞지만, 하나 더 해줘야 할 것이 있습니다. ListView의 특성상, 부모 위젯의 영향을 받기 때문에, 부모를 하나 만들어 사이즈를 정해주어야 합니다. ListView를 Axis.horizontal을 하게 되면, 높이가 무제한이 되기 때문에 사이즈 부모를 꼭 넣어줘야 합니다.

body: SizedBox(
   height: 200,
   child: ListView(
       scrollDirection: Axis.horizontal,
       children: [
           Container(
              width: 1000,
              height: 3,
              decoration: BoxDecoration(
                  gradient: LinearGradient(
                      colors: [
                         Colors.red,
                         Colors.blue,
                      ],
                  ),
              ),
           ),
       ],
   ),
),

오늘의 실습

// ignore_for_file: prefer_const_constructors, sized_box_for_whitespace, unused_local_variable
// ignore_for_file: prefer_const_literals_to_create_immutables

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
      home: Scaffold(
        bottomNavigationBar: BottomNavigationBar(
          type: BottomNavigationBarType.fixed,
          items: [
            BottomNavigationBarItem(
                icon: Icon(Icons.laptop_chromebook_sharp), label: '강의'),
            BottomNavigationBarItem(
              icon: Icon(Icons.favorite),
              label: '즐겨찾기',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.search),
              label: '검색',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.comment_rounded),
              label: '커뮤니티',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.person),
              label: '나의 정보',
            ),
          ],
        ),
        appBar: AppBar(
          centerTitle: true,
          elevation: 0,
          title: Text('스나이퍼팩토리앱'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: ListView(
            children: [
              Container(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(16),
                ),
                child: ListTile(
                  contentPadding:
                      const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
                  leading: CircleAvatar(
                    radius: 24,
                    backgroundImage: NetworkImage('<https://picsum.photos/200>'),
                  ),
                  title: Text(
                    'Teddy Lee',
                    style: TextStyle(fontWeight: FontWeight.bold),
                  ),
                  subtitle: Text('SniperFactory Teacher'),
                  trailing: Icon(Icons.search),
                ),
              ),
              const SizedBox(
                height: 8,
              ),
              Text(
                '수업인증',
                textAlign: TextAlign.left,
                style: TextStyle(
                    color: Colors.white,
                    fontSize: 18,
                    fontWeight: FontWeight.bold),
              ),
              const SizedBox(
                height: 8,
              ),
              Container(
                height: 140,
                child: ListView(
                  scrollDirection: Axis.horizontal,
                  children: [
                    Container(
                      margin: const EdgeInsets.only(right: 8),
                      clipBehavior: Clip.hardEdge,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(24),
                      ),
                      child: Image.network('<https://picsum.photos/300>'),
                    ),
                    Container(
                      margin: const EdgeInsets.only(right: 8),
                      clipBehavior: Clip.antiAlias,
                      decoration: BoxDecoration(
                        shape: BoxShape.circle,
                      ),

                      // decoration: BoxDecoration(
                      //   borderRadius: BorderRadius.circular(24),
                      // ),
                      child: Image.network('<https://picsum.photos/400>'),
                    ),
                    Container(
                      margin: const EdgeInsets.only(right: 8),
                      clipBehavior: Clip.hardEdge,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(24),
                      ),
                      child: Image.network('<https://picsum.photos/500>'),
                    ),
                    Container(
                      margin: const EdgeInsets.only(right: 8),
                      clipBehavior: Clip.hardEdge,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(24),
                      ),
                      child: Image.network('<https://picsum.photos/600>'),
                    ),
                  ],
                ),
              ),
              const SizedBox(
                height: 16,
              ),
              Text(
                '설정찾기',
                textAlign: TextAlign.left,
                style: TextStyle(
                    color: Colors.white,
                    fontSize: 18,
                    fontWeight: FontWeight.bold),
              ),
              const SizedBox(
                height: 8,
              ),
              Container(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(16),
                  color: Colors.white12,
                ),
                child: Column(
                  children: [
                    ListTile(
                      leading: Icon(Icons.light_mode),
                      title: Text('테마변경'),
                    ),
                    ListTile(
                      leading: Icon(Icons.favorite),
                      title: Text('즐겨찾는 과정 '),
                    ),
                    ListTile(
                      leading: Icon(Icons.calendar_month),
                      title: Text('과정 일정 관리'),
                    ),
                    ListTile(
                      leading: Icon(Icons.home),
                      title: Text('홈화면 설정'),
                    ),
                  ],
                ),
              ),
              const SizedBox(
                height: 8,
              ),
              Container(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(16),
                  color: Colors.white12,
                ),
                child: Column(
                  children: [
                    ListTile(
                      leading: Icon(
                        Icons.subscriptions,
                        color: Colors.redAccent,
                      ),
                      title: Text('결제관리'),
                    ),
                    ListTile(
                      leading: Icon(
                        Icons.shopping_bag,
                        color: Colors.purpleAccent,
                      ),
                      title: Text('장바구니'),
                    ),
                    ListTile(
                      leading: Icon(
                        Icons.history_edu_rounded,
                        color: Colors.green,
                      ),
                      title: Text('결제이력'),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
728x90

'개발 > Flutter' 카테고리의 다른 글

Flutter 여섯 번째 강의 내용  (0) 2022.11.01
Flutter 네 번째 강의 내용  (0) 2022.10.24
Flutter 세 번째 강의 내용  (0) 2022.10.21
Flutter 두 번째 강의 내용  (0) 2022.10.20
Flutter 첫 번째 강의 내용  (0) 2022.10.18
728x90

Text 위젯

Text위젯의 속성 중에 style이라고 있다. style에는 넣을 수 있는 데이터 타입은 무엇인가? Type: TextStyle이다.

TextStyle에 대해 알아보자.

글자를 우리가 원하는대로 색을 넣거나, 크기를 조정하거나 할 수 있다.

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('비밀 게시판'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: ListView(
            children: [
              ListTile(
                title: Text('공지사항'),
                subtitle: Text(
                  '반갑습니다. 여러분',
                  style: TextStyle(
                    color: Colors.green,
                    fontSize: 24,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                leading: Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Icon(Icons.book),
                ),
                trailing: Icon(Icons.navigate_next),
              ),
              ....,
							....,
            ],
          ),
        ),
      ),
    );
  }

AppBar

지금까지 사용했던 속성은 leading, title, centerTitle, backgroundColor이고, 오늘 추가로 배워볼 속성은 foregroundColor, titleTextStyle, actions이다.

  1. leading: 앱바에 제일 앞에오는 위젯을 설정할 수 있음
  2. title : 앱의 타이틀(주로 텍스트 혹은 이미지)을 설정할 수 있음
  3. centerTitle : 타이틀을 가운데로 설정할 것인지
  4. backgroundColor : 앱바의 배경색을 결정
  5. foregroundColor : 앱바의 기본 표현 색을 결정
  6. titleTextStyle : title이 Text위젯을 썼다면, 적용할 텍스트 스타일 (foregroundColor 보다 힘 쌤 )
  7. actions : 앱 바 제일 뒤에 오는 위젯을 설정할 수 있음. 주의사항 AppBar는 trailing이 아니라 actions로 배열이 들어간다.

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('연락처'),
          centerTitle: false,
          backgroundColor: Colors.white,
          foregroundColor: Colors.black,
          elevation: 0,
          actions: [
            Icon(Icons.settings),
            Icon(Icons.settings),
          ],
        ),
      ),
    );
  }

CircleAvatar 위젯

보통 아바타를 그릴 때 사용. 이미지와 함께 사용하여 동그란 이미지를 제공한다. 프로필 사진 혹은 채팅방 명, 로고 등의 이미지를 보여주기에 좋다.

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('연락처'),
          centerTitle: false,
          backgroundColor: Colors.white,
          foregroundColor: Colors.black,
          elevation: 0,
        ),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: ListView(
            children: [
              ListTile(
                title: Text('빈 유저'),
                leading: CircleAvatar(),
              ),
            ],
          ),
        ),
      ),
    );
  }

child안에 들어갈 위젯을 제공한다, 텍스트 위젯을 이용해서 이미지가 없을 경우 연락처의 경우 한 글자만 넣는 경우가 있다.

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('연락처'),
          centerTitle: false,
          backgroundColor: Colors.white,
          foregroundColor: Colors.black,
          elevation: 0,
          actions: [
            Icon(Icons.settings),
            Icon(Icons.settings),
          ],
        ),
        body: ListTile(
          leading: CircleAvatar(
            child: Text('빈'),
          ),
          title: Text('빈 유저'),
        ),
      ),
    );
  }

child 에 아이콘 위젯을 넣을 경우

프로필 사진 등을 구현하려 할 때, child를 넣어 이미지 위젯을 부르는 것보다는 backgroundImage를 사용하는 것이 추천된다.

backgroundImage: Image.network(’<https://picsum.photos/200’>),

Image.network()로 구현하면 오류가 나는 것을 확인할 수 있다.

그 이유는 backgroundImage 속성은 위젯을 전달받지 않는다. ImageProvider의 데이터형태만 전달받는다.

ImageProvider인 데이터 형태의 종류는 크게 4가지이다.

  • NetworkImage
  • AssetImage
  • FileImage
  • MemoryImage

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('연락처'),
          centerTitle: false,
          backgroundColor: Colors.white,
          foregroundColor: Colors.black,
          elevation: 0,
          actions: [
            Icon(Icons.settings),
            Icon(Icons.settings),
          ],
        ),
        body: ListTile(
          leading: CircleAvatar(
            backgroundImage: NetworkImage('<https://picsum.photos/200>'),
          ),
          title: Text('환경 설정'),
        ),
      ),
    );
  }

CircleAvatar 위젯

adius(반지름)의 크기를 키워 아바타의 사이즈를 정해줄 수 있다.

radius라는 속성에 입력된 int(정수)의 수를 조정하여 크기 조절할 수 있다.

body: CircleAvatar(
          radius: 100,
          backgroundImage: NetworkImage('<https://picsum.photos/200>'),
        ),

Scaffold의 능력

Scaffold의 속성 중, appBar와 body에 위젯을 각각 넣었었다.

바로 흔히 말하는 [바텀네비게이션바, BottomNavigationBar] 그리고 [FAB, FloatfingActionBar]

BottomNavigationBar 위젯

어플은 화면을 나누어 특정한 목적을 달성하기 시키기 위한 스크린들이 존재한다.

카카오톡 → 친구창 / 채팅방 리스트 / 쇼핑 / 내 설정 인스타그램 → 피드 / 검색 / 릴스 / 쇼핑 / 내 피드

Scaffold가 이러한 기능을 사용할 수 있도록 속성을 제공한다.

BottomNavigationBar 위젯은 BottomNavigationBarItem이 하나만 있으면 오류가 발생한다.

bottomNavigationBar: BottomNavigationBar(
          items: [
            BottomNavigationBarItem(icon: Icon(Icons.call), label: '연락처'),
            BottomNavigationBarItem(icon: Icon(Icons.block), label: '차단'),
            BottomNavigationBarItem(icon: Icon(Icons.settings), label: '설정'),
          ],
        ),

BottomNavigationBar는 items라는 속성을 필수(required)로 받습니다. 그 안은 무조건 BottomNavigationBarItem만 올 수 있다.

BottomNavigationBar는 조건이 있습니다.

  1. 여러 페이지를 위해 제공되는 거라서 버튼(BottomNavigationBarItem)이 두 개 이상이어야 함
  2. 각 BottomNavigationBarItem에 label속성을 넣어줍니다.

FloatingActionButton 위젯

floatingActionButton: FloatingActionButton(
          onPressed: () {},
        ),
        bottomNavigationBar: BottomNavigationBar(
          items: [
            BottomNavigationBarItem(icon: Icon(Icons.call), label: '연락처'),
            BottomNavigationBarItem(icon: Icon(Icons.block), label: '차단'),
            BottomNavigationBarItem(icon: Icon(Icons.settings), label: '설정'),
          ],
        ),
728x90

'개발 > Flutter' 카테고리의 다른 글

Flutter 여섯 번째 강의 내용  (0) 2022.11.01
Flutter 다섯 번째 강의 내용  (0) 2022.10.27
Flutter 세 번째 강의 내용  (0) 2022.10.21
Flutter 두 번째 강의 내용  (0) 2022.10.20
Flutter 첫 번째 강의 내용  (0) 2022.10.18
728x90

column과 Row는 기본 값

column과 Row는 기본값이 있어서 crossAxisAlignment: CrossAxisAlignment.start를 붙여줘야 한다.

body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('오늘 수업도!'),
              Text('오늘 수업도!'),
              Container(
                height: 40,
              ),
              Text('이력'),
              Text('멍때리기 대회 1등'),
              Text('밥 천천히 먹기 1등'),
            ],
          ),
        ),

padding 위젯

Padding 위젯을 넣어주면 부모와 자식 사이의 간격이 벌어집니다.

Padding 위젯의 필수 속성인 padding에다가 EdgeInsets.all(원하는 간격) 넣기

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('내 정보 앱'),
          centerTitle: false,
        ),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('이름: 박현성'),
              Text('나이: 26'),
              Text('성별: 남자'),
              Container(
                height: 40,
              ),
              Text('이력'),
              Text('멍때리기 대회 1등'),
              Text('밥 천천히 먹기 대회 1등'),
              Text('치킨 많이 먹기 대회 1등'),
            ],
          ),
        ),
      ),
    );
  }

EdgeInsets 이란

  • 마진, 패딩 등의 여백을 줄 때 사용하는 데이터 타입

EdgeInsets.all(4) → 상하좌우 전부 4만큼만 띄워줘.

EdgeInsets.all(8) → 상하좌우 전부 8만큼만 띄워줘.

EdgeInsets.only(left: 8) → 왼쪽에서 8만큼만 띄워줘.

EdgeInsets.LTRB(20,15,10,5) → 왼 20, 위 15, 오 10, 아래 5 만큼 띄워줘.

margin과 padding 차이

padding은 Container의 안쪽 영역의 여백

margin은 Container의 바깥 영역의 여백이다.

 

Container 위젯

자식 위젯을 하나로 묶어서 관리하기 좋은 위젯, 컨테이너로 감싼다.

주로 둥글게 깎거나, 사이즈를 넣어주거나, 색상을 넣어주거나, 간격을 띄워주는 등 많은 기능이 있음.

body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Container(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text('이름: 박현성'),
                Text('나이: 26'),
                Text('성별: 남자'),
                Container(
                  height: 40,
                ),
                Text('이력'),
                Text('멍때리기 대회 1등'),
                Text('밥 천천히 먹기 대회 1등'),
                Text('치킨 많이 먹기 대회 1등'),
              ],
            ),
          ),
        ),

Container에서 함께 쓰는 속성들 중 오늘 살펴볼 자주 쓰이는 속성

color : 컨테이너의 색상 width : 컨테이너의 넓이 (픽셀) height : 컨테이너의 높이 (픽셀) child : 자식 위젯

body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Container(
            color: Colors.red,
            width: 100,
            height: 150,
          ),
        ),

Icon 위젯

앱에 들어가는 아이콘을 가져올 수 있는 아이콘 위젯, Material Icon들을 기본적으로 사용할 수 있다.

https://fonts.google.com/icons?selected=Material+Icons

Icon 위젯 안에, Icons. 입력하면, 자동완성 기능을 통해 아이콘을 삽입할 수 있음.

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('내 정보 앱'),
          centerTitle: false,
        ),
        body: Row(
          children: [
            Icon(
              Icons.person,
            ),
            Icon(
              Icons.phone,
            ),
            Icon(
              Icons.settings,
            ),
          ],
        ),
      ),
    );
  }

ListTile 위젯

목록을 통해서 보여주고 싶은 정보를 일자로 나열할 때 일관성을 유지하기 위함

title에 Text위젯을 넣어 이름을 넣고, subtitle에 Text위젯을 넣어 번호를 입력한 뒤에, leading의 속성에 Icon 혹은 Avatar를 넣을 수 있음.

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('내 정보 앱'),
          centerTitle: false,
        ),
        body: ListTile(
          title: Text('박현성'),
          subtitle: Text('010-0000-0000'),
          leading: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Icon(Icons.person),
          ),
          trailing: Icon(Icons.phone),
        ),
      ),
    );
  }

ListTile의 가장 기본은, title속성 (한 줄)로 만들어져 있기 때문에 subtitle속성이 들어오며 두 줄이 되어 기존의 아이콘에 추가 간격이 필요하다. 우린 이걸 Padding 위젯을 넣어 해결해줄 수 있다.

leading은 가장 앞에 둘 때, trailing은 가장 뒤에 둘 때, trailing의 속성 값에 Icon위젯을 넣을 수 있다.

import 'package:flutter/material.dart';
// ignore_for_file: prefer_const_constructors

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('연락처 앱'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Container(
            width: 350,
            height: 200,
            color: Colors.grey,
            child: Center(
              child: Text(
                '안녕하세요',
              ),
            ),
          ),
        ),
      ),
    );
  }
}

화면에 너무 많이 입력하면, 화면상에 표현할 수 있는 높이를 벗어나게 됨.

SingleChildScrollView 위젯

자식에게 스크롤이 가능하도록 스크롤 기능을 제공, Column에게 사용해주면, 스크롤을 사용하여 오버플로우가 일어나지 않도록 해준다.

주로 Column, Row가 함께 많이 쓰이며, 사이즈가 클 것 같거나 핸들링하기 어려운 사이즈의 위젯을 다룰 때 좋다.

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('내 정보 앱'),
          centerTitle: false,
        ),
        body: SingleChildScrollView(
          child: Column(
            // ignore: prefer_const_literals_to_create_immutables
            children: [
              ListTile(
                title: Text('박현성'),
                subtitle: Text('010-0000-0000'),
                leading: Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Icon(Icons.person),
                ),
                trailing: Icon(Icons.phone),
              ),
							....
							....
            ],
          ),
        ),
      ),
    );
  }

  • Column 위젯은, 본인이 차지할 수 있는 무한대의 수직 영역을 사용한다. 하지만 그렇기 때문에, 화면이 넘치면 어떻게 할 줄 모르는데, SingleChildScrollView 위젯 = 스크롤 능력을 주기
  • 근데 이 둘의 장점을 하나로 합쳐서 사용할 수 있는 것이 ListView위젯, 기본 행동(behavior)이 스크롤이 들어가 있다.
@override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('내 정보 앱'),
          centerTitle: false,
        ),
        body: ListView(
          // ignore: prefer_const_literals_to_create_immutables
          children: [
            ListTile(
              title: Text('박현성'),
              subtitle: Text('010-0000-0000'),
              leading: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Icon(Icons.person),
              ),
              trailing: Icon(Icons.phone),
            ),
            ....,
						....
          ],
        ),
      ),
    );
  }

 

728x90

'개발 > Flutter' 카테고리의 다른 글

Flutter 다섯 번째 강의 내용  (0) 2022.10.27
Flutter 네 번째 강의 내용  (0) 2022.10.24
Flutter 두 번째 강의 내용  (0) 2022.10.20
Flutter 첫 번째 강의 내용  (0) 2022.10.18
Flutter 환경 구성 및 설치  (2) 2022.10.14
728x90

플러터 첫 프로젝트 만들기

Visual Studio Code에서 커멘드 창을 연다. 단축키로는 command + shift + p이고 직접 실행하는 방법은 View에서 Command Palette이다.

 

Flutter: New Project를 누르면 아래와 같은 사진이 나오는데 Application을 클릭한다.

 

그러면 이제 폴더를 선택하는 창이 나온다. 원하는 폴더에 위치시키고 Select a folder to create the project in을 누르면 된다.

 

이제 원하는 프로젝트 이름을 입력해주면 된다.

 

Flutter 폴더 구조 확인하기

플러터를 프로젝트를 만들면 많은 양의 폴더와 파일들이 생성되는데 겁먹지 말고 사용하는 것만 주로 사용한다고 한다.

초급에서 볼 필요 없는 것들

.dart_tool, .idea, flutter_scrap.iml, pubspec.lock, README.md 파일 등이 있다.

차츰차츰 알아서 습득 될 것들

android, ios, linux, macos, web, windows, test 등이 있다.

초급 이어도 필수로 알아야 할 것들

lib, pubspec.yaml 이 있다.

lib 폴더

흔히 Library 폴더라고 한다. 줄여서 lib이라고 표기한다.

우리가 작성하는 모든 코드가 lib 폴더에서 작성된다.

기본적으로 main.dart 파일이 들어가 있다.

pubspec.yaml

앱을 만들 때 필요한 패키지나 이미지, 폰트 등을 등록하는 설정 파일이다.

main.dart

앱의 시작점이라서, 이 파일이 없으면 오류 나고 실행이 안됨

플러터 프로젝트 생성 시에 기본적으로 생성되는 파일

실행할 디바이스 선택

visual studio Code 하단 바에 macOS를 클릭한다.

 

클릭하면 상단에 어떤 디바이스를 선택할 것인지 창이 나온다.

 

이제 프로젝트를 실행시키면 된다.

프로그램의 시작점

  1. lib/main.dart 실행
  2. main.dart 안의 main을 찾기
  3. main 안에 runApp을 찾기
import 'package:flutter/material.dart';
// ignore_for_file: prefer_const_constructors

void main() => runApp(MyApp());
  1. material.dart라는 패키지를 사용하겠다.
  2. main을 실행하면, runApp을 실행시킬 것이고, runApp은 MyApp을 실행시킨다.

새로운 줄에서 stl만 입력하면 자동으로 Flutter stateless Widget이라는 영역이 생긴다.

Flutter stateless Widget을 선택한다. 자동완성 기능이라고 생각하면 된다. 정식 명칭으로는 snippet이다

 

return Container() 부분을 MaterialApp으로 변경한다.

 

글자가 왼쪽 상단에 잘려서 보이는 것을 확인할 수 있다.

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Text("안녕하세요 키키"),
      ),
    );
  }
}

MaterialApp 위젯

  • 구글은, 일관성 있는 모바일 디자인을 추구했는데, 그 결과 구글의 머티리얼 디자인이 탄생했다. https://material.io/design/ 에서 확인할 수 있는 디자인 가이드가 있다.
  • 그 일관성 있는 디자인을 사용할 수 있도록 초기 틀을 잡아주는 역할
  • 즉, 그림 그리기 전 도화지를 준비해 놓는 것과 같다고 생각하면 좋다.
  • 가장 최상위의 위젯 (최상위의 부모)라서 단 하나의 MaterialApp 안에 여러 위젯들이 살 수 있음

Scaffold 위젯

  • 그래서 그 머티리얼 위젯을 사용할 수 있도록 실제 건축 준비를 해주는 친구
  • Scaffold 위젯에 AppBar 위젯을 넣을 수도 있고, 공중에 떠있는 버튼도 넣어볼 수 있다

MaterialApp + Scaffold는 짝꿍이고, 99%의 모든 앱이 함께 쓰고 있다. 같이 쓰는 위젯 정도로 외우면 좋다

SafeArea 위젯 디바이스마다, 카메라 노치나 아이폰 M자 탈모 등의 요소 화면 시작점이 각각 다르니 시작점을 통일하기 위해 사용

import 'package:flutter/material.dart';
// ignore_for_file: prefer_const_constructors

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Text("안녕하세요 키키"),
        ),
      ),
    );
  }
}

Text 위젯

글자나 숫자 등을 화면상에 보여줄 때 사용하는 위젯, 바로 반드시 String형태의 데이터를 넘겨주자 이때 Strin형태의 데이터란, 따옴표로 감싼 문자열이다.

Center 위젯

자식 위젯을 가운데로 위치할 수 있도록 능력을 주는 부모

import 'package:flutter/material.dart';
// ignore_for_file: prefer_const_constructors

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Center(
            child: Text("안녕하세요 키키"),
          ),
        ),
      ),
    );
  }
}

AppBar 위젯

어플에서 앱바를 그려줄 수 있는 위젯, 반드시 부모 위젯이 Scaffold여야 한다. 왜냐하면, Scaffold위젯 기능 중에 AppBar를 쓸 수 있는 기능이 있기 때문임.

여기서 알 수 있는 Scaffold 기능

  1. AppBar에 위젯을 넣을 수 있다.
  2. Body에도 위젯을 넣을 수 있다.
import 'package:flutter/material.dart';
// ignore_for_file: prefer_const_constructors

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("내 정보 앱"),
        ),
        body: SafeArea(
          child: Center(
            child: Text("안녕하세요 키키"),
          ),
        ),
      ),
    );
  }
}

 

그리고 앱바에는 다양한 기능을 넣어줄 수 있는데, 테스트해보기 좋은 기능들은 다음과 같다 ( backgroundColor, centerTitle )

 

bool, 불리언이라고 불리며 값은 진실(true) 혹은 거짓(false)밖에 없다. 여기에서는 파란색으로 색깔이 구분된다.

centerTitle: false,

Column 위젯

텍스트로 개행 문자(\n)를 넣어서 해줄 수 있지만, 위젯은 다음 줄에 못 넣는다. 위젯들을 수직방향으로 나열하고 싶을 경우 사용한다, child가 아닌, child의 복수형인 children을 사용한다 (다수의 위젯을 갖기에)

  • 기본값으로, 수직적으로 빈 영역이 있으면 다 차지해버리는 설계 방식
import 'package:flutter/material.dart';
// ignore_for_file: prefer_const_constructors

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.purple,
          centerTitle: false,
          title: Text("내 정보 앱"),
        ),
        body: SafeArea(
          child: Column(
            children: [
              Text("안녕하세요 키키"),
              Text("안녕하세요 키키"),
              Text("안녕하세요 키키"),
            ],
          ),
        ),
      ),
    );
  }
}

 

Image.network 위젯

모든 이미지를 불러와서 사용할 수 있다. 하지만, 이미지를 어디서 가져오냐가 중요하다.

  1. 이미 업로드돼있는 네트워크를 통해 (인터넷, 웹)에서 가져올 경우 = Image.network()
// ignore_for_file: prefer_const_constructors

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.purple,
          centerTitle: false,
          title: Text('내 정보 앱'),
        ),
        body: SafeArea(
            child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Image.network(
                '<https://search.pstatic.net/common/?src=http%3A%2F%2Fblogfiles.naver.net%2FMjAyMjEwMDNfNTMg%2FMDAxNjY0ODAyNTk1OTMx.y-L9TXW9UQd4RjloZNI8_O8rKTZyfvbp2fLF2eZzNPog.zPQxjOaiSPPEkuDUFUWxJGzahFjzxybxVQz1SFy1pYwg.JPEG.kmcmodooall%2F1664802595768.jpg&type=sc960_832>'),
            Text('이름: 박현성'),
            Text('나이: 26'),
            Text('성별: 남자'),
          ],
        )),
      ),
    );
  }
}

 

현재까지 배운 데이터 타입은 (String, int, bool, widget) 총 4가지, 근데 위젯마다 사용하는 방법이 다르다.

예를 들어서

  1. Center 위젯의 child는 Widget을 넣을 수 있다.
  2. Text 위젯의 값은 String만 넣을 수 있다.
  3. Scaffold 위젯의 키 appBar의 값은 Widget만 넣을 수 있다.
  4. Scaffold 위젯의 키 body의 값은 Widget만 넣을 수 있다.
  5. Image.network 위젯의 값은 String만 넣을 수 있다.

Tips.

// ignore_for_file: prefer_const_constructors

위의 코드를 주석 달린 채로 작성하면 파란색 물결 밑줄 표시가 사라진다.

 

부모 자식 관계 자동완성

command +  . 이다.

 

728x90

'개발 > Flutter' 카테고리의 다른 글

Flutter 다섯 번째 강의 내용  (0) 2022.10.27
Flutter 네 번째 강의 내용  (0) 2022.10.24
Flutter 세 번째 강의 내용  (0) 2022.10.21
Flutter 첫 번째 강의 내용  (0) 2022.10.18
Flutter 환경 구성 및 설치  (2) 2022.10.14
728x90

hello world

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
          child: Text('Hello World'),
        ),
      ),
    );
  }

위의 코드의 구조를 보면 아래의 구조와 같습니다.

색상 코드 작성 방법

색상을 바꾸는 코드 코드 색상표 구글에 검색하면 헥스 코드가 나온다.

Dart에서 색상을 입힐 때 0xFF작성하고 헥스 코드 # 뒤에부터 나머지를 작성하면 된다.

backgroundColor: Color(0xFFB22222),//Color(0xFF00FF00),//Color(0xFFFFBC00),//Color(0xFFFF0500), //Color(0xFF0034FF),

Text 위젯

Text위젯에는 항상 String이 따라오므로 다른 데이터 타입이 들어오면 안 된다.

title: Text('Welcome to Flutter'),

아래의 코드를 작성하면 Text 위젯 안에 Integer 타입이 들어가 있어 오류가 난다.

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
       body: Text(01234567)
      ),
    );
  }
}

Flutter의 Widget은 SPA의 컴포넌트 개념과 유사하다고 표현할 수 있습니다.

화면의 틀, 가운데 정렬을 위한 Center, 여백을 위한 Padding, 그리고 텍스트 삽입을 위한 Text 등 모두가 Widget이라고 이해하면 됩니다.

MaterialApp

MaterialApp은 구글 스타일의 디자인 틀을 제공하는 위젯입니다.

MaterialApp을 사용하기 위해서는 아래의 코드를 import해주어야합니다.

import 'package:flutter/material.dart';

CupertinoApp

CupertinoApp 애플 스타일의 디자인 틀을 제공하는 위젯입니다.

CupertinoApp을 사용하기 위해서는 아래의 코드를 import 해주어야 합니다.

import 'package:flutter/cupertino.dart';

Container 위젯

Container 위젯은 화면의 요소들을 담고 있는 하나의 박스로 비유할 수 있습니다.

width, height, color 등의 속성을 이용하여 박스의 크기와 색상을 설정할 수 있고, 내부에 여러 위젯들을 활용하여 내용을 구성하면 됩니다.

child

Material Design에서 body는 오로지 하나의 위젯만을 가집니다. 여러 가지 위젯을 내부에 포함시키기 위해서는, 위젯들의 배열을 내부에 가질 수 있는 타입의 위젯을 body의 child로 설정하는 것이 필요합니다. Flutter에서 위젯의 배열을 child로 가질 수 있는 여러가지 위젯들이 존재합니다. 여기서 사용하는 Row/Column 위젯도 이들 중 하나입니다.

Column은 세로로 배치하는 위젯이고, Row는 가로로 배치하는 위젯입니다.

보통 CrossAxisAlignment와 MainAxisAlignment의 여러 속성들 (ex. start, end, center, spaceEvently, spaceBetween 등)을 활용하여 알맞은 간격을 조정합니다.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext ctxt) {
    return new MaterialApp(
      title: "MySampleApplication",
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("Hello Flutter App"),
        ),
        body: new Center(
          child: new Row(
            children: <Widget>[
              new Text("Hello Flutter"),
              new Text("Hello Flutter - "),
            ],
          ),
        ), 
      )
    );
  }
}
728x90

'개발 > Flutter' 카테고리의 다른 글

Flutter 다섯 번째 강의 내용  (0) 2022.10.27
Flutter 네 번째 강의 내용  (0) 2022.10.24
Flutter 세 번째 강의 내용  (0) 2022.10.21
Flutter 두 번째 강의 내용  (0) 2022.10.20
Flutter 환경 구성 및 설치  (2) 2022.10.14
728x90

개요

이번에 스나이퍼 팩토리에서 주관하는 Flutter 앱 개발 과정 교육에 참여하게 되어서 Flutter 환경을 제 맥북 M1에 세팅하려고 한다.

Flutter 환경을 구성하려면 아래와 같은 6가지의 설치 과정이 필요하다.

  1. Android Studio
  2. Xcode
  3. Chrome
  4. Flutter SDK
  5. VSCode
  6. VSCode Extension - Flutter

1. Android Studio 설치 과정

https://developer.android.com/studio에 접속한다.

녹색 표시의 다운로드 버튼을 누른다.

 

녹색 버튼을 누르게 되면 위와 같은 창이 나온다. 저는 Mac의 Apple chip M1 이므로 흰 바탕의 버튼을 눌러서 설치를 진행했다.

다운로드한 위치에 android-studio-2021.3.1.16-mac_arm.dmg 파일이 생성되는데 이 파일을 실행시켜준다. 설치 중에 나오는 체크사항은 모두 디폴드로 진행한다.

 

2. Xcode 설치 과정

 

Xcode는 App Store에서 설치를 진행하면 된다.

 

App store에 접속해서 검색창에 xcode를 검색하면 Apple Developer와 Xcode가 나오는데 Xcode만 설치를 진행한다.

 

3. Chrome 설치

Chrome은 다들 설치되어있을 것이라 생각하고 생략하겠습니다.

 

4. Flutter SDK를 설치한다.

https://docs.flutter.dev/get-started/install/macos 이 링크에 접속한다.

링크에 접속하면 위와 같은 화면이 나오는데 Apple Slilcon인 flutter_macos_arm64_3.3.4-stable.zip을 설치한다.

설치가 완료되면 압축을 해제해줍니다.

터미널에 접속해서 Flutter SDK 압축 풀어준 경로로 접속합니다.

 

export PATH="$PATH:`pwd`/flutter/bin"

위의 환경 변수를 추가해줍니다.

 

터미널에서 zshrc 파일을 열고

open ~/.zshrc

 

Path 추가하는 라인을 복붙 해주고 파일을 저장한다. 경로를 잘 확인합시다.

export PATH=$PATH:~/Downloads/flutter/bin

 

그리고 터미널에서 source 명령어를 입력해서 zshrc파일을 재실행한다.

source ~/.zshrc

 

플러터 명령어가 잘 실행되는지 확인하기 위해 아래의 코드를 터미널에 입력해 봅니다.

flutter --version

 

출력 내용

Flutter 3.3.4 • channel stable • <https://github.com/flutter/flutter.git>
Framework • revision eb6d86ee27 (8일 전) • 2022-10-04 22:31:45 -0700
Engine • revision c08d7d5efc
Tools • Dart 2.18.2 • DevTools 2.15.0

 

5. VSCode 설치

https://code.visualstudio.com/ 이 링크에 접속해서 VSCode를 설치합니다.

VSCode를 실행시켜줍니다.

 

6. VSCode Extension - Flutter 설치

VSCode를 실행시킨 화면에서 왼쪽 하단에 있는 사각형 4개 있는 아이콘을 클릭합니다.

 

검색창에 flutter를 검색해서 다운로드하여줍니다.

 

7. Flutter가 잘 설치되어있는지 점검을 해주는 Run Flutter Doctor를 실행한다.

Shift+Command+P 단축키로 Pallete를 실행하고 Flutter: Run Flutter Doctor를 실행한다.

 

만약 SDK 경로를 못 찾는다고 나오면 경로 찾아서 Set 해주면 된다. 경로는 Flutter SDK 압축 해제한 폴더에서 flutter/bin 까지 추가해준다.

output 영역에 실행 결과가 나오는데 2개의 카테고리에 문제가 있다고 나올 것이다 현재 저는 오류를 수정해서 오류 화면이 나오지 않습니다.

 

8. Android SDK command-line Tools를 설치해야 한다.

일단 Android Studio를 실행하고 상단에 Preferences 메뉴를 선택한다.

 

9. 왼쪽의 Android SDK 메뉴의 중간에 있는 SDK Tools 메뉴에서 Android SDK command-line Tools를 체크하고 Apply 하면 된다.

 

10. flutter doctor --android-licenses를 터미널에서 실행한다.

y / n이 나오면 y를 입력해준다.

 

11. 이제 Xcode 이슈를 해결한다.

아래의 명령어를 터미널에서 실행시켜 cocoapods를 설치한다.

sudo gem install cocoapods -n /usr/local/bin

 

pod도 설치한다.

pod setup

 

아래의 코드를 실행시킨다.

sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -runFirstLaunch

 

12. 최종 확인

다시 flutter doctor를 실행해서 issues가 없음을 확인한다.

 

728x90

'개발 > Flutter' 카테고리의 다른 글

Flutter 다섯 번째 강의 내용  (0) 2022.10.27
Flutter 네 번째 강의 내용  (0) 2022.10.24
Flutter 세 번째 강의 내용  (0) 2022.10.21
Flutter 두 번째 강의 내용  (0) 2022.10.20
Flutter 첫 번째 강의 내용  (0) 2022.10.18

+ Recent posts