안녕하세요 😉
유유자적한 개발자 유로띠 입니다 😀
👏👏👏👏
이번 포스팅에서는
✅ 컨테이너 위젯
✅ 여백 스타일 위젯
✅ 배치 및 공간 제어 위젯
✅ 이미지 위젯
✅ 동적 위젯
✅ 버튼
에 대해서 알아보겠습니다
컨테이너 위젯
✅ 단일 컨테이너 위젯
📍 Container
Container 안에는 다음과 같은 기능이 존재합니다.
body: Container(
color: Colors.yellow,
alignment: Alignment.center,
margin: const EdgeInsets.symmetric(
horizontal: 100,
vertical: 100
),
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 10
),
child: const Text('hello world!!'),
)
🟢 color
컨테이너의 색을 조정합니다.
color: Colors.yellow,
🟢 alignment
왼쪽, 오른쪽, 가운데 정렬 등 정렬을 조정합니다.
숫자를 이용하여 세밀한 정렬이 가능합니다.
alignment: const Alignment(0,0), // (0,0) = center
alignment: const Alignment.center,
🟢 width
가로길이를 조정합니다.
🟢 height
세로 길이를 조정합니다.
🟢 child
내용을 구성합니다.
child: const Text('hello world!!'),
🟢 margin
밖 쪽 여백이 생깁니다.
margin: const EdgeInsets.symmetric(
horizontal: 100,
vertical: 100
),
🟢 padding
안쪽 여백이 생깁니다.
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 10
),
Container에서 width, height만 사용하면 sizedBox를 사용하면 됩니다.
📍 SizedBox
간단하게 child의 width, height 사이즈를 조절합니다.
body: const SizedBox(
width: 200,
height: 200,
child: Text('hello world!'),
)
📍 Center
중앙 정렬된 컨테이너를 생성하려면 다음처럼 작성하면 됩니다.
body: const Center(
child: Text('hello world!'),
)
✅ 복수 컨테이너 위젯
📍 Column
컨테이너를 여러 개 생성할 때 세로축으로 정렬합니다.
MainAxisAlignment는 Column이며, crossAxisAlignment는 Row입니다.
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
color: Colors.yellow,
alignment: Alignment.center,
width: 40,
height: 40,
child: const Text('1'),
),
Container(
color: Colors.red,
alignment: Alignment.center,
width: 70,
height: 70,
child: const Text('2'),
),
Container(
color: Colors.blue,
alignment: Alignment.center,
width: 100,
height: 100,
child: const Text('3'),
),
],
)
📍 Row
컨테이너를 여러개 생성할 때 가로축으로 정렬합니다.
body: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
color: Colors.yellow,
alignment: Alignment.center,
width: 100,
height: 40,
child: const Text('1'),
),
Container(
color: Colors.red,
alignment: Alignment.center,
width: 100,
height: 70,
child: const Text('2'),
),
Container(
color: Colors.blue,
alignment: Alignment.center,
width: 100,
height: 100,
child: const Text('3'),
),
],
)
📍 Wrap
overflow의 발생을 방지합니다.
그림처럼 3번째 박스가 크기가 커서 overflow일 때 자동으로 밀려 오른쪽에 위치됩니다.
direction를 통해 가로축(horizontal), 세로축 지정(vertical)
body: Wrap(
direction: Axis.vertical,
children: [
Container(
color: Colors.yellow,
alignment: Alignment.center,
width: 40,
height: 200,
child: const Text('1'),
),
Container(
color: Colors.red,
alignment: Alignment.center,
width: 70,
height: 200,
child: const Text('2'),
),
Container(
color: Colors.blue,
alignment: Alignment.center,
width: 100,
height: 200,
child: const Text('3'),
),
여백 스타일 위젯
✅ padding
padding은 컨테이너가 존재합니다.
📍 EdgeInsetsGeometry Type
//여백 제거
margin: EdgeInsets.zero
// left, top, right, bottom 동일한 여백을 주고 싶을 때
margin: EdgeInsets.all(40),
//left, top, right, bottom 설정
margin: EdgeInsets.fromTRB(10, 20, 50, 100),
//특정 위치(left, top, right, bottom)에만 여백을 주고 싶을 때
margin: EdgeInsets.only(bottom: 100),
//가로, 세로 별로 여백을 주고 싶을 때
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
배치 및 공간 제어 위젯
✅ Align
정렬을 조정할 때 사용합니다.
body: Alin(
alignment: Alignment.center,
),
✅ Spacer
특정 위치에 여백을 설정할 때 사용한다.
flex를 이용하여 공백의 크기를 설정할 수 있다.
1번 박스와 2번 박스 사이에 Spacer의 flex 값 1을 주었고 2번 박스와 3번 박스 사이에 Spacer의 flex 값 2를 주었습니다.
body: Row(
children: [
Container(
color: Colors.yellow,
alignment: Alignment.center,
width: 40,
height: 40,
child: const Text('1'),
),
const Spacer(
flex: 1,
),
Container(
color: Colors.red,
alignment: Alignment.center,
width: 40,
height: 40,
child: const Text('2'),
),
const Spacer(
flex: 2,
),
Container(
color: Colors.blue,
alignment: Alignment.center,
width: 40,
height: 40,
child: const Text('3'),
),
Container(
color: Colors.green,
alignment: Alignment.center,
width: 40,
height: 40,
child: const Text('4'),
),
],
)
✅ Expanded
나머지 영역 안에 내용을 작성할 때 사용한다.
body: Row(
children: [
Container(
color: Colors.yellow,
alignment: Alignment.center,
width: 40,
height: 40,
child: const Text('1'),
),
const Spacer(),
Container(
color: Colors.red,
alignment: Alignment.center,
width: 40,
height: 40,
child: const Text('2'),
),
const Expanded(
child: Text('값을 입력할 때 expanded를 사용한다.'),
),
Container(
color: Colors.blue,
alignment: Alignment.center,
width: 40,
height: 40,
child: const Text('3'),
),
Container(
color: Colors.green,
alignment: Alignment.center,
width: 40,
height: 40,
child: const Text('4'),
),
],
)
이미지 위젯
✅ AssetImage
로컬 이미지를 표시할 때 사용합니다.
📍 pubspec.yaml
이미지를 첨부한 경로를 지정합니다.
단일 파일을 지정하여도 되고, 해당 폴더 하위의 모든 이미지를 가져올 수도 있습니다.
# 단일 이미지 파일
assets:
- assets/images/image.jpg
# images 하위 폴더의 이미지 파일 전부
assets:
- assets/images/
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
Image.asset('assets/images/image1.JPG'),
Image.asset('assets/images/image2.JPG'),
],
),
);
}
✅ NetworkImage
네트워크를 통한 이미지를 가져올 때 사용합니다.
플러터가 이미지 파일을 다운로드해서 캐시에 저장하고 화면에 출력합니다.
asset 이미지 방식보다 로딩이 느리며, 인터넷 연결이 필요합니다.
Scaffold(
appBar: AppBar(),
body: Column(
children: [
Image.network('https://ww.namu.la/s/86c340753dc5e6e09e441a01a25d2f15dc4d6df1c59088aca212f69a9f2be855cfd9fa0d84281de2508da01e40ac2dbf1e9614b64fcbcfb62c22be931e9c97b083a56303b32b7c38ea4ba17a299e78da7ea1a6f0c2e17b632269c1a00c147a85'),
Image.network(
'http://file3.instiz.net/data/file3/2020/03/14/3/7/f/37f2fc88c1eabe693f6b03c103d21855.gif',
fit: BoxFit.fitWidth,
width: 300,
height: 300,
),
],
),
);
아래의 코드처럼 사용 할 수도 있습니다.
Image(
image: AssetImage('assets/images/image1.JPG'),
)
Image(
image: NetworkImage(
'http://file3.instiz.net/data/file3/2020/03/14/3/7/f/37f2fc88c1eabe693f6b03c103d21855.gif'
),
)
✅ File
외부 폴더나 갤러리에 있는 이미지를 가져올 때는 File을 사용합니다.
Image.file(file),
✅ 공통 속성
위에 3가지 이미지 위젯은 width, height, BoxFit이라는 공통 속성을 가지고 있습니다.
width, heigth는 기본적인 것이라 아실 테고 BoxFit에 대해서 알아보겠습니다.
📍 fill
사이즈에 맞춰 비율을 왜곡하여 이미지를 변형해 채웁니다.
📍 contain (default)
이미지가 잘리지 않고 정해진 사이즈 안에서 비율이 변하지 않고 그려집니다.
📍 cover
이미지 비율은 유지한 채, 사이즈 벗어나면 이미지가 잘린 채 출력됩니다.
📍 fitWidth
width(너비) 사이즈에 맞춰 채워서 그립니다.
📍 fitHeight
height(높이) 사이즈에 맞춰 채워서 그립니다.
📍 none
원본 이미지 표시 경우에 따라 이미지 잘릴 수 있습니다.
📍 scaleDown
전체 이미지가 나올 수 있게 이미지 크기를 조절해서 기본값으로 가운데 맞춤으로 출력합니다.
💡 참고
동적 위젯
✅ stateful widget
값에 따라 화면에 반영할 때에는 StatefulWidget을 사용합니다.
statelessWidget에서 StatefulWidget으로 변경하는 방법은 간단합니다.
Convert to StatefulWidget를 선택하여 기존 코드를 변경할 수 있습니다.
버튼 클릭 시 숫자가 올라가는 카운팅 앱을 만들어 봅시다.
import 'package:flutter/material.dart';
class LottsHomePage extends StatefulWidget {
LottsHomePage({ Key? key }) : super(key: key);
@override
State<LottsHomePage> createState() => _LottsHomePageState();
}
class _LottsHomePageState extends State<LottsHomePage> {
int count = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Lotts Home Page')),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: (){
//build를 다시 호출하여 다시 그린다.
setState(() {
count++;
});
print(count);
},
onLongPress: (){
setState(() {
count = 0;
});
},
style: ElevatedButton.styleFrom(
primary: Colors.orange,
onPrimary: Colors.black,
),
child: const Text('plus'),
),
Center(
child: Text('$count'),
)
],
)
);
}
}
int count = 0;으로 초기화해줍니다.
setState(() {});를 사용하면 build를 다시 실행하여 새롭게 그립니다.
화면에 변경된 정보를 확인할 수 있습니다.
버튼
✅ ElevatedButton
✅ OutlineButton
✅ TextButton
3개의 버튼은 생성자 형태가 동일하기 때문에 한 번에 설명드리겠습니다.
body: Column(
children: [
ElevatedButton(
onPressed: (){
print('ElevatedButton - onPressed');
},
onLongPress: (){
print('ElevatedButton - onLongPress');
},
// button 스타일은 여기서 작성한다.
style: ElevatedButton.styleFrom(
primary: Colors.orange,
onPrimary: Colors.black,
),
child: const Text('ElevatedButton')
),
OutlinedButton(
onPressed: (){},
child: const Text('OutlinedButton')
),
TextButton(
onPressed: (){},
child: const Text('TextButton')
),
GestureDetector(
onTap: (){},
child: const Text('GestureDetector')
),
],
)
📍 onPressed
버튼 클릭 시 발생하는 이벤트입니다.
📍 onLongPress
버튼을 길게 클릭 시 발생하는 이벤트입니다.
📍 style
버튼의 스타일을 관리합니다.
✅ GestureDetector
클릭 시 이벤트를 가져가기 위한 버튼입니다.
주황색 화면을 클릭하면 이벤트가 발생합니다.
body: Column(
children: [
GestureDetector(
onTap: (){
print('GestureDetector');
},
child: Container(
color: Colors.orange,
height: 100,
)
),
],
)
✅ FloatingActionButton
다른 버튼과 달리 Scaffold 안에 floatingActionButton이 존재합니다.
오른쪽 하단에 동그라미 버튼이 생성됩니다.
Scaffold(
appBar: AppBar(
title: const Text('Lotts Home Page')),
floatingActionButton:
FloatingActionButton(
onPressed: (){},
child: const Icon(
Icons.plus_one,
color: Colors.white,
),
),
);
📍 onPressed
버튼 클릭 시 발생하는 이벤트입니다.
📍 Icon
다양한 아이콘을 사용할 수 있습니다.
이상
flutter 기본
위젯과 버튼에 대해 알아보았습니다.
'Programming > flutter' 카테고리의 다른 글
Mac OS에서 CocoaPods 설치 시 에러 해결 방법 (0) | 2023.02.11 |
---|---|
flutter 패키지 매니저 pub.dev 사용하기 (fluttertoast 사용해보기) (0) | 2022.09.16 |
flutter 프로젝트 생성 및 iPhone에서 실행해보기(for Mac) (0) | 2022.03.18 |
Mac에서 Flutter 설치하기(feat. android studio, xcode) (1) | 2022.03.17 |