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

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

+ Recent posts