코드팩토리의 플러터 프로그래밍 (책_플러터 위젯 템플릿)
위젯 실습용 템플릿 작성
[ 기본코드 ]
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: // 1 여기에 예제 코드 작성하기
),
),
);
}
}
텍스트 관련 위젯
화면에 글자를 보여주려면 글자를 렌더링할 수 잇는 위젯을 사용해야 한다.
[ Text 위젯 ]
Text 위젯은 글자를 적고 스타일링 하는 위젯이다. 첫번째 포지셔널 파라미터에 원하는 문자열을 작성하고 style이라는 네임드 파라미터를 사용해 스타일을 지정한다.
child: Text(
// 작성하고 싶은 글
'코드팩토리',
// 글자에 스타일 적용
style: TextStyle(
// 글자 크기
fontSize: 16.0,
// 글자 굵기
fontWeight: FontWeight.w700,
// 글자 색상
color: Colors.blue,
),
),
제스처 관련 위젯
사용자가 키보드로 글자를 입력하는 행위 외의 모든 입력을 플러터에서는 제스처라고 부른다.
예를 들어 화면을 한 번 탭한다거나, 두 번 탭한다거나 길게 누르는 행동 모두가 제스처이다.
제스처 관련 위젯은 하위 위젯에 탭이나 드래그처럼 특정 제스처가 입력됐을 때 인지하고 콜백 함수를 실행한다.
[ Button 위젯 ]
플러터 머터리얼 패키지에서 기본 제공하는 버튼으로 TextButton, OutlinedButton, ElevatedButton이 있다. 버튼을 누르면 색깔이 변경되는 리플 효과를 지원한다.
- TextButton
TextButton(
// 클릭 시 실행
onPressed: () {},
// 스타일 지정
style: TextButton.styleFrom(
// 주 색상 지정
foregroundColor: Colors.red,
),
// 버튼에 넣을 위젯
child: Text('텍스트 버튼'),
),
- OutlinedButton
OutlinedButton(
// 클릭 시 실행할 함수
onPressed: () {},
// 버튼 스타일
style: OutlinedButton.styleFrom(
foregroundColor: Colors.red,
),
// 버튼에 들어갈 위젯
child: Text('아웃라인드 버튼'),
)
- ElevatedButton
ElevatedButton(
// 클릭 시 실행할 함수
onPressed: (){},
// 버튼 스타일링
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
),
// 버튼에 들어갈 위젯
child: Text('엘레베이티드 버튼'),
),
[ IconButton 위젯 ]
아이콘을 버튼으로 생성하는 위젯이다. icon 매개변수에 보여주고 싶은 아이콘을 넣을 수 있다.
onPressed 매개변수에 IconButton을 누르면 실행할 콜백 함수를 제공할 수 있다.
아이콘은 글리프 기반의 아이콘을 사용할 수 있으며 Icon클래스를 통해 제공하는 기본 아이콘들을 사용할 수 있다.
글리프란?
탭바, 버튼, 네비게이션바 등의 인터페이스 요소에 들어갈 공통적인 것들을 표현하기 위한 것
알아보기 쉽게, 매우 간단하게
앱의 모든 glyph는 시각적으로 일관성 되게 유지
IconButton(
onPressed: () {},
icon: Icon(
// 1 플러터에서 기본으로 제공하는 아이콘입니다.
// 제공되는 아이콘 목록은 다음 링크에서 확인해볼 수 있습니다.
// https://fonts.google.com/icons
Icons.home,
),
)
[ GestureDetector 위젯 ]
앱은 모든 입력을 손가락으로 한다. 그래서 손가락으로 하는 여러 가지 입력을 인지하는 위젯이 필요한데 그걸 gestureDetector가 그 역할을 한다.
GestureDetector(
// 1 한 번 탭했을 때 실행할 함수
onTap: () {
// 출력 결과는 안드로이드 스튜디오의 [Run] 탭에서 확인 가능합니다.
print('on tap');
},
// 2 두 번 탭했을 때 실행할 함수
onDoubleTap: () {
print('on double tap');
},
// 3 길게 눌렀을 때 실행할 함수
onLongPress: () {
print('on long press');
},
// 제스처를 적용할 위젯
child: Container(
decoration: BoxDecoration(
color: Colors.red,
),
width: 100.0,
height: 100.0,
),
),
위젯에 한번 탭 두 번 탭, 길게 눌렀을때의 예제코드가 있다. 이뿐만이 아니라 웹에서의 오른쪽 클릭, 위젯 드래그 등의 입력도 받을 수 있다.
매개변수 | 설명 |
onTap | 한 번 탭했을 때 실행되는 함수를 입력할 수 있습니다. |
onDoubleTap | 두 번 연속으로 탭했을 때 실행되는 함수를 입력할 수 있습니다. |
onLongPress | 길게 누르기가 인식됐을 때 실행되는 함수를 입력할 수 있습니다. |
onPanStart | 수평 또는 수직으로 드래그가 시작됐을 때 실행되는 함수를 입력할 수 있습니다. |
onPanUpdate | 수평 또는 수직으로 드래그를 하는 동안 드래그 위치가 업데이트될 때마다 실행되는 함 수를 입력할 수 있습니다. |
onPanEnd | 수평 또는 수직으로 드래그가 끝났을 때 실행되는 함수를 입력할 수 있습니다. |
onHorizontalDragStart | 수평으로 드래그를 시작했을 때 실행되는 함수를 입력할 수 있습니다. |
onHorizontalDragUpdate | 수평으로 드래그를 하는 동안 드래그 위치가 업데이트될 때마다 실행되는 함수를 입력할 수 있습니다. |
onHorizontalDragEnd | 수평으로 드래그가 끝났을 때 실행되는 함수를 입력할 수 있습니다. |
onVerticalDragStart | 수직으로 드래그를 시작했을 때 실행되는 함수를 입력할 수 있습니다. |
onVerticalDragUpdate | 수직으로 드래그를 하는 동안 드래그 위치가 업데이트될 때마다 실행되는 함수를 입력할 수 있습니다. |
onVerticalDragEnd | 수직으로 드래그가 끝났을 때 실행되는 함수를 입력할 수 있습니다. |
onScaleStart | 확대가 시작됐을 때 실행되는 함수를 입력할 수 있습니다. |
onScaleUpdate | 확대가 진행되는 동안 확대가 업데이트될 때마다 실행되는 함수를 입력할 수 있습니다. |
onScaleEnd | 확대가 끝났을 때 실행되는 함수를 입력할 수 있습니다. |
[ FloatingAction Button 위젯 ]
Material Design에서 추구하는 버튼 형태이다. 앱들을 사용하다 보면 화면의 오른쪽 아래에 동그란 플로팅 작업 버튼을 쉽게 볼 수 있다.
FloatingActionButton과 Scaffold를 같이 사용하면 특별한 어려움 없이 해당 형태의 디자인을 구현할 수 있다.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
floatingActionButton: FloatingActionButton(
// 클릭했을 때 실행할 함수
onPressed: () {
print('클릭');
},
child: Text('클릭'),
),
body: Container(),
),
);
}
}
디자인 관련 위젯
디자인 관련 위젯은 배경을 추가하거나 간격을 추가하거나 패딩을 추가하는 등 디자인적 요소를 적용할 때 사용한다.
[ Container 위젯 ]
다른 위젯을 담는데 사용되고 너비와 높이를 지정하거나 배경이나 테두리를 추가할 때 많이 사용된다.
Container위젯은 다른 위젯들처럼 child 매개변수를 사용할 수 있다.
Container(
// 스타일 작용
decoration: BoxDecoration(
// 배경 색깔 적용
color: Colors.red,
// 테두리 적용
border: Border.all(
// 테두리 굵기
width: 16.0,
// 테두리 색상
color: Colors.black,
),
// 모서리 둥글게 만들기
borderRadius: BorderRadius.circular(
16.0,
),
), // 높이
height: 200.0,
// 너비
width: 100.0,
)
[ SizedBox 위젯 ]
위젯은 일반적으로 일정 크기의 공간을 공백으로 두고 싶을 때 사용된다. Container 위젯을 사용해도 공백을 만들 수 있지만
SizedBox는 const 생성자를 사용했을 때 퍼포먼스에서 이점을 얻을 수 있다.
SizedBox(
// 높이 지정
height: 200.0,
// 너비 지정
width: 200.0,
// SizedBox는 색상이 없으므로 크기를 확인하는
// 용도로 Container 추가
child: Container(
color: Colors.red,
),
) //
[ Padding 위젯 ]
child 위젯에 여백을 제공할 떄 사용한다. 상위 위젯과 하위 위젯 사이의 여백을 둘 수 있다. padding 매개변수는 EdgeInsets라는 값을 입력해야한다. 또한 child 매개변수에 Padding을 적용하고 싶은 위젯을 입력할 수 있다.
Padding(
// 상하, 좌우로 모두 16픽셀만큼 패딩 적용
padding: EdgeInsets.all(
16.0,
),
child: Container(
color: Colors.red,
width: 50.0,
height: 50.0,
),
),
패딩은 적용된 위젯이 차지하는 크기 내부에서 간격이 추가된다. 마진은 따로 위젯이 존재하지 않고 Container위젯에 추가할 수 있다.
EdgeInsets 클래스는 다양한 생성자를 제공한다.
생성자 | 설명 |
EdgeInsets.all(16.0) | 상하, 좌우로 매개변수에 입력된 패딩을 균등하게 적용합니다. |
EdgeInsets.symmetric(horizontal: 16.0,vertical: 16.0) | 가로와 세로 패딩을 따로 적용합니다. Horizontal 매개변수에 가로로 적용할 패딩을 입력하고 Vertical 매개변수에 세로로 적 용할 패딩을 입력합니다. |
EdgeInsets.only(top: 16.0, bottom: 16.0, left:16.0, right: 16.0) | 위아래, 좌우 패딩을 따로 적용합니다. top, bottom, left, right 매개변수에 각각 위아래 좌우 패딩을 입력할 수 있습니다. |
EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 16.0) | 위아래, 좌우 패딩을 따로 적용합니다. 포지셔널 파라미터를 좌, 위, 우, 아래 순서로 입력해주면 됩니다. |
[ SafeArea ]
플러터는 가용되는 화면을 모두 사용하기 때문에 아이폰처럼 노치가 있는 핸드폰에서 노치에 위젯들이 가릴 수 있다.
SafeArea위젯을 사용하면 따로 기기별로 예외처리를 하지 않고도 안전한 (Safe)화면에서만 위젯을 그릴 수 있다.
배치 관련 위젯
하위 위젯을 가로 또는 세로로 배치하거나 위젯 위에 위젯을 겹칠 떄 사용한다.
[ Row 위젯 ]
가로로 위젯을 배치하는데 사용되고 children매개변수를 노출한다.
주축과 반대축이라는 개념이 존재하는데 row는 가로가 주축, 세로가 반대축이 되고, Column의 경우 반대가 된다.
import 'package:flutter/material.dart';
void main() {
runApp(RowWidgetExample());
}
class RowWidgetExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SizedBox(
// 반대축에서 이동할 공간을 제공하기 위해 높이를 최대한으로 설정
height: double.infinity,
child: Row(
// 주축 정렬 지정
mainAxisAlignment: MainAxisAlignment.start,
// 반대축 정렬 지정
crossAxisAlignment: CrossAxisAlignment.center,
// 넣고 싶은 위젯 입력
children: [
Container(
height: 50.0,
width: 50.0,
color: Colors.red,
),
// SizedBox는 일반적으로 공백을
// 생성할 때 사용
const SizedBox(width: 12.0),
Container(
height: 50.0,
width: 50.0,
color: Colors.green,
),
const SizedBox(width: 12.0),
Container(
height: 50.0,
width: 50.0,
color: Colors.blue,
),
],
),
),
),
);
}
}
[ Column 위젯 ]
Row위젯과 완전히 같은 매개변수들을 노출한다. 다만 주축과 반대축이 Row와 반대로 이루어져 있다.
import 'package:flutter/material.dart';
void main() {
runApp(ColumnWidgetExample());
}
class ColumnWidgetExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SizedBox(
// 반대축에서 이동할 공간을 제공해주기 위해 너비를 최대한으로 설정
width: double.infinity,
child: Column(
// 주축 정렬 지정
mainAxisAlignment: MainAxisAlignment.start,
// 반대축 정렬 지정
crossAxisAlignment: CrossAxisAlignment.center,
// 넣고 싶은 위젯 입력
children: [
Container(
height: 50.0,
width: 50.0,
color: Colors.red,
),
// SizedBox는 일반적으로 공백을 생성할 때 사용
const SizedBox(width: 12.0),
Container(
height: 50.0,
width: 50.0,
color: Colors.green,
),
const SizedBox(width: 12.0),
Container(
height: 50.0,
width: 50.0,
color: Colors.blue,
),
],
),
),
),
);
}
}
[ Flexible 위젯 ]
Row나 Column에서 사용하는 위젯이다. Flexible에 제공된 child가 크기를 최소한으로 차지할 수 있다. 추가적으로 flex매개변수를 이용해 flexible위젯이 얼만큼의 비율로 공간을 차지할지 지정할 수 있다.
Column(
children: [
Flexible(
// flex는 남은 공간을 차지할 비율을 의미합니다.
// flex값을 제공하지 않으면 기본값은 1입니다.
flex: 1,
// 파란색 Container
child: Container(
color: Colors.blue,
),
),
Flexible(
flex: 1,
// 빨간색 Container
child: Container(
color: Colors.red,
),
)
],
),
[ Expanded 위젯 ]
Flexible위젯을 상속하는 위젯이다.
Column과 Row에서 Expanded를 사용하면 위젯이 남아 있는 공간을 최대한으로 차지한다.
Flexible위젯은 fit 매개변수에 FlexFit.tight 또는 FlexFit.loose를 입력할 수 있다. FlexFit.loose는 자식 위젯이 필요한 만큼만 공간을 차지한다. 하지만 FlexFit.tight는 자식 위젯이 차지하는 공간과 관계없이 남은 공간을 모두 차지한다. Expanded위,젯은 Flexible위젯의 fit 매개변수에FlexFit.tight 를 기본으로 제공해주는 위젯으로 남는 공간을 최대한으로 차지하게 된다.
Column(
children: [
// 파란색 Container
Expanded(
child: Container(
color: Colors.blue,
),
),
// 빨간색 Container
Expanded(
child: Container(
color: Colors.red,
),
)
],
)),
[ Stack 위젯 ]
Stack위젯은 위젯을 겹치는 기능을 제공한다. 플러터는 그래픽엔진인 스키아 엔진은 2D 엔진이기 때문에 겹친 두께를 표한하지는 못하지만 Stack를 사용하면 위젯 위에 위젯을 올린 듯한 효과를 줄 수 있다.
Stack(
children: [
// 빨간색 Container
Container(
height: 300.0,
width: 300.0,
color: Colors.red,
),
// 노란색 Container
Container(
height: 250.0,
width: 250.0,
color: Colors.yellow,
),
// 파란색 Container
Container(
height: 200.0,
width: 200.0,
color: Colors.blue,
),
],
),
Stack는 children에 위치한 순서대로 위젯을 겹쳐싼다. 컨테이너가 점점 가로, 세로, 50 픽셀씩 작아지고 있어 먼저 그려진 컨테이너가 가로 세로 50픽셀만큼 더 크게 그려진다.