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

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