[개발일지] flutter 앱개발 2주차
<스파르타코딩 flutter 강의 수강일지>
2주차: 사용자가 보는 화면 만들기
1. Flutter Widget
1) Stateless vs Stateful
Stateless: 상태변화 X -> 새로고침 X | Stateful: 상태변화 O -> 새로고침 O |
*setState()는 Stateful에서 동작한다.
/// Stateless Widget
class MyWidget extends StatelessWidget {
const MyWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
}
}
/// Stateful Widget
class MyWidget extends StatefulWidget {
const MyWidget({Key? key}) : super(key: key);
@override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
@override
Widget build(BuildContext context) {
}
}
2) 기본 위젯: Text / Container / Icon / Image
// Text
Text(
'텍스트 위젯',
style: TextStyle(
fontSize: 35, // 폰트 크기
fontWeight: FontWeight.bold, // 폰트 두께
color: Colors.amber, // 폰트 색상
),
),
// Container
Container(
width: 200, // 폭
height: 200, // 높이
color: Colors.pinkAccent, // 박스 색상
child: Text("I Love Flutter!"), // 자식 위젯
padding: EdgeInsets.all(20), // 박스 안쪽 영역
margin: EdgeInsets.all(50), // 박스 바깥 영역
alignment: Alignment.topLeft, // child 정렬
),
// Material Icon
Icon(
Icons.home,
color: Colors.blue,
size: 50,
),
// Cupertino Icon
Icon(
CupertinoIcons.house,
color: Colors.pink,
size: 50,
),
// Image Network
Image.network(
'https://i.ibb.co/CwzHq4z/trans-logo-512.png',
width: 150,
),
*EdgeInsets (Padding/Margin)
// 전방위
EdgeInsets.all(8)
// 특정 방위만 적용
EdgeInsets.only(
left: 8,
right: 8,
)
//수직, 수평으로 적용
EdgeInsets.symmetric(
vertical: 8,
horizontal: 8,
)
*BoxDecoration
Container(
width: 200,
height: 200,
// color : Colors.amber, // decoration와 함께 사용 불가
decoration: BoxDecoration(
color: Colors.amber, // decoration 안에 color를 활용해주세요.
borderRadius: BorderRadius.circular(50), // 모서리를 둥글게
border: Border.all(color: Colors.blue, width: 5), // 테두리
boxShadow: [
BoxShadow(
// 그림자 효과
color: Colors.grey.withOpacity(0.7), // 투명도 70% 회색
spreadRadius: 5, // 퍼짐 효과
blurRadius: 7, // 뭉갬 효과
offset: Offset(5, 5), // 그림자를 우측 5 아래 5만큼 이동
),
],
),
);
Material Icon 모아보기
https://fonts.google.com/icons?selected=Material+Icons
Material Symbols and Icons - Google Fonts
Material Symbols are our newest icons consolidating over 2,500 glyphs in a single font file with a wide range of design variants.
fonts.google.com
Cupertino Icon 모아보기
https://shuuji3.xyz/flutter-packages/third_party/packages/cupertino_icons/
Cupertino Icons 1.0.0 Gallery
shuuji3.xyz
3) 레이아웃(Layout) 위젯: Scaffold / Column / Row / Stack / SingleChildScrollView
*SingleChildScrollView와 Listview.builder는 같이 쓰지 않는다.
Scaffold
Scaffold(
appBar: AppBar(), // 상단 바
body: Text(), //화면 중앙에 가장 큰 면적
bottomNavigationBar: BottomNavigationBar(), //하단 바
floatingActionButton: FloatingActionButton(), //우측 하단
),
Column / Row
Column(
children: [
// 자식 위젯들
Text("위젯1"),
Text("위젯2"),
],
// 세로 방향에 대한 크기
mainAxisSize: MainAxisSize.max, // 부모를 가득
mainAxisSize: MainAxisSize.min, // 자식 크기만큼
// 세로 방향 정렬
mainAxisAlignment: MainAxisAlignment.center, // 중앙
mainAxisAlignment: MainAxisAlignment.start, // 시작
mainAxisAlignment: MainAxisAlignment.end, // 끝
mainAxisAlignment: MainAxisAlignment.spaceBetween, // 양 끝에 배치하고 등분
mainAxisAlignment: MainAxisAlignment.spaceAround, // 균등하게 나누고 공간의 절반을 뒤에
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 등분
// 가로 방향 정렬
crossAxisAlignment: CrossAxisAlignment.center, // 중앙
crossAxisAlignment: CrossAxisAlignment.start, // 시작
crossAxisAlignment: CrossAxisAlignment.end, // 끝
crossAxisAlignment: CrossAxisAlignment.stretch, // 늘려 가득 채움
),
// Column과 가로 세로 반대
Row(
children: [
// 자식 위젯들
Text("위젯1"),
Text("위젯2"),
],
),
Stack: 쌓아 올림
Stack(
children: [ // 자식 위젯들
Text("위젯1"),
Text("위젯2"),
],
),
SingleChildScrollView: 위젯이 스크린보다 클 때, 스크롤 할 수 있도록 함.
SingleChildScrollView(
child: Container(height: 10000), // 자식 위젯
),
3. 텍스트 입력: TextField
TextField(
autofocus: true, // 자동 포커스
onChanged: (text) {
// 텍스트 변경시 실행되는 함수
},
onSubmitted: (text) {
// Enter를 누를 때 실행되는 함수
},
),
4. 클릭 이벤트: Button
// 위로 올라와 있는 듯한 버튼
ElevatedButton(
onPressed: () {
print("Elevated Button 클릭");
},
child: Text('Elevated Button'),
),
// 텍스트 버튼
TextButton(
onPressed: () {
print("Text Button 클릭");
},
child: Text('Text Button'),
),
// 아이콘 버튼
IconButton(
onPressed: () {
print("Icon Button 클릭");
},
icon: Icon(Icons.add),
),
5. 화면 이동: Navgator.push / pop
// 다음 페이지로 이동
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()), // 이동하려는 페이지
);
// 현재 화면 종료
Navigator.pop(context); // 종료
6. 공백 위젯: Spacer, Sizedbox, Divider
// 가로 세로 일정 간격 줄 때
SizedBox(height: 20),
SizedBox(width: 20),
// 사이 공간을 꽉 채울 때
Spacer()
// 구분선 넣을 때
Divider()
2. 실습과제
ClipRRect: 모서리를 둥글게
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8),
topRight: Radius.circular(8),
),
child: Image.network(
imageUrl,
fit: BoxFit.fitHeight,
height:
MediaQuery.of(context).size.width * 0.4,
),
),
GestureDetector: 탭, 더블탭 등 제스처에 함수 할당
GestureDetector(
onTap: () {
DefaultTabController.of(context)?.animateTo(0);
}, // 탭할 때 함수 실행
child: Column(
children: [
Icon(Icons.person, color: Colors.white),
Text(
'라이브러리',
style: TextStyle(color: Colors.white),
),
],
),
),
SafeArea: 노치 혹은 상단 스테이터스 바 영역 비워줌
SafeArea(
child: Scaffold(
appBar: AppBar(),
),
);
Positioned: 위치 조정
Stack(
children: [
Positioned(
left: 28.0,
top: 20.0,
child: UserProfileImage(
imageURL: room.speakers[1].imageUrl,
size: 48,
),
),
UserProfileImage(
imageURL: room.speakers[0].imageUrl,
size: 48,
)
],
),
TabBar / TabBarView: 탭하여 다른 내용 보여줌
// AppBar에 넣음
TabBar(
tabs: [
Tab(text: "Chats"),
Tab(text: "Requests"),
],
),
),
// Body에 넣음
TabBarView(
children: [
ListView.builder(
itemCount: backChannelRoomsList.length,
itemBuilder: (context, index) {
return BackChannelRoomCard(
backChannelRoom: backChannelRoomsList[index]);
},
),
Center(
child: Text(
"👍 You're all good!\nYou don't have any new\nmessage requests.",
textAlign: TextAlign.center,
),
),
],
),
ListTile: 리스트 형식의 타일
ListTile(
leading: FlutterLogo(size: 72.0),
title: Text('Three-line ListTile'),
subtitle: Text(
'A sufficiently long subtitle warrants three lines.'
),
trailing: Icon(Icons.more_vert),
isThreeLine: true,
),