앱이 시작될 때 무조건 사용하는 위젯
문서: https://api.flutter.dev/flutter/material/MaterialApp-class.html
MaterialApp 위젯을 main()에서 호출하여 처음 앱이 실행될 수 있도록 합니다.
void main() {
runApp(MaterialApp(
title: '앱 이름',
initialRoute: '/', // 시작할 화면 위젯의 String Path
routes: {
HomeScreen.routeName: (context) => HomeScreen(),
// '/': (context) => const HomeScreen(),
},
theme: ThemeData(
// 다양한 기본 위젯 옵션들을 정의
),
home: HomeScreen(), // initialRoute 대신 클래스 직접 호출하는 방식
));
}
화면을 그릴 때 제일 먼저 사용하는 위젯
Widget 클래스를 상속하는 추상 클래스 StatefulWidget과 StatelessWidget이 있습니다. (두 위젯에 대한 비교 내용은 다음 포스팅에서 이어집니다.)
문서: https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html
문서에도 나와있는 대로 동적으로 변하는 UI를 표현하고 싶을 때 구현하기 좋습니다.
IntelliJ에서 제공하는 'Flutter Code Template' 에서는 'stful' 이라고 입력하면 기본 코드 형태가 자동완성이 됩니다.
// TestView 라는 위젯을 만들었을 때 생성된 기본 코드
import 'package:flutter/material.dart'; // 코드 생성 후에 import 에러가 나면 material로 import 해주세요.
class TestView extends StatefulWidget {
const TestView({Key? key}) : super(key: key);
_TestViewState createState() => _TestViewState();
}
class _TestViewState extends State<TestView> {
Widget build(BuildContext context) {
return Container();
}
}
_TestViewState 클래스의 build() 메서드의 리턴 값에서 UI가 그려집니다.
_TestViewState 클래스 내에 변수를 선언해놓고 상태를 변경하고 싶을 때 아래의 코드를 호출합니다.
setState(() {
});
문서: https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html
StatefulWidget으로 모든 화면을 구현할 수 있지만 어떤 상호작용으로 인해 UI가 변화하는 위젯이 아닐 때 사용합니다.
import 'package:flutter/material.dart'; // 코드 생성 후에 import 에러가 나면 material로 import 해주세요.
class TestView extends StatelessWidget {
const TestView({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Container();
}
}
TestView 클래스에서 전역 변수를 생성하려고 하면 경고가 뜹니다. 관련링크: must be immutable
StatefulWidget 처럼 UI가 바뀌는 동작에 대한 수행을 할 수도 없습니다.
Flutter에서 위젯을 다시 빌드하는 동작을 최소화하려고 한다는 내용을 문서에서도 확인할 수 있는데, 이를 위해서라도 꼭 StatefulWidget으로 사용하지 않아도 될 부분이면 StatelessWidget으로 구현하면 되겠습니다.
문서: https://api.flutter.dev/flutter/material/Scaffold-class.html
앱 화면 하나를 작성할 때 build() 메서드에서 반환할 위젯 중 가장 최상위에 Scaffold 위젯을 사용합니다.
appBar 필드에서 화면 최상단에 표시할 위젯들을 정의합니다. (굳이 필요 없으면 선언하지 않으면 됩니다.)
body 필드에서 화면을 표현합니다.
문자열을 화면에 보여주는 위젯
Text 위젯을 꾸미려면 style 필드에 TextStyle 객체를 넣어 원하는 옵션을 추가하면 됩니다.
main()에서 선언한 MaterialApp 위젯 안에서 textTheme을 설정해놓고 사용하는 것도 가능합니다.
만약 폰트를 적용하고 싶다면 프로젝트에 폰트 파일을 추가하고 pubspec.yaml에 사용할 폰트파일을 명시해야 합니다. (자세한 사용방법은 pubspec.yaml 사용 방법에서...)
문서: https://api.flutter.dev/flutter/material/TextField-class.html
문자 입력을 받는 위젯
controller 필드에 TextEditingController 인스턴스를 넣으면, TextField 안에 입력한 값을 제어할 수 있습니다.
문서: https://docs.flutter.dev/release/breaking-changes/buttons
3가지 종류의 버튼 위젯: TextButton, ElevatedButton, OutlinedButton
상황에 맞는 버튼을 골라 쓰면 되는데, 만약 버튼 위젯으로 구현이 어렵다 싶은 디자인이면 GestureDetector 위젯을 사용합니다. (자세한 사용방법은 'GestureDetector' 에서...)
이미지 버튼이 따로 없어서 버튼 위젯 안에다 이미지를 넣게 되면 풀사이즈 이미지 버튼이 나오지 않고 테두리에 버튼 위젯 고유 테두리가 입혀집니다. (만들고 싶으면 위의 방법 사용)
style 필드에 버튼 디자인을 좀더 자세하게 작성합니다.
child 필드에 버튼 내용을 위젯으로 작성합니다.
Android LinearLayout과 거의 비슷한 Row, Column 위젯
ListView, GridView
복수의 위젯을 포함하는 위젯들은 children 필드 내에 리스트 형태로 지정합니다.
Row 문서: https://api.flutter.dev/flutter/widgets/Row-class.html
Column 문서: https://api.flutter.dev/flutter/widgets/Column-class.html
Row는 가로 방향으로, Column은 세로 방향으로 위젯들을 나열합니다.
mainAxisAlignment, crossAxisAlignment 필드를 통해 여러 개의 위젯들을 상황마다 정렬이 가능합니다.
ListView 문서: https://api.flutter.dev/flutter/widgets/ListView-class.html
GridView 문서: https://api.flutter.dev/flutter/widgets/GridView-class.html
수평이나 수직으로 스크롤이 가능하도록 위젯들을 포함합니다.
ListView/GridView에 담기는 모든 위젯들이 같은 UI 형태를 띄고 있다면 ListView.builder/GridView.builder 위젯으로 사용하는 것이 깔끔합니다.
ListView 내부에 Card 위젯과 ListTile 위젯을 사용해 기본적인 ListView 위젯의 항목들을 그릴 수도 있습니다. (리스트 항목 내에 그려야 할 요구사항이 많아지면 위젯을 직접 그리는 것이 편할 것입니다.)
Stack 문서: https://api.flutter.dev/flutter/widgets/Stack-class.html
Stack: 위젯을 독립적인 위치에 고정시키거나 어떤 위젯 위에 겹쳐서 위젯을 보이고 싶을 때 사용합니다.
원하는 위치에 위젯을 그리기 위해 Align 위젯을 사용해 처음 위치를 지정하고 그리기 시작하면 편리합니다.
SizedBox 문서: https://api.flutter.dev/flutter/widgets/SizedBox-class.html
위젯의 크기를 특정 크기로 제한할 때 사용합니다.
아무것도 표현하지 않는 위젯을 그릴 때는 'const SizedBox.shrink()' 로 보통 사용합니다.
Container 문서: https://api.flutter.dev/flutter/widgets/Container-class.html
위젯의 크기를 특정 크기로 제한하거나, 특정 영역에 사각형, 원 등의 모양을 낼 때 사용합니다.
Container 위젯을 꾸밀 때는 color 필드와 decoration 필드 둘 중 하나만 사용합니다.
decoration 필드에 들어갈 객체는 BoxDecoration 클래스입니다. 문서
decoration 값을 통해 사각형과 원 모양을 다양하게 꾸밀 수 있습니다.
color나 decoration을 사용하지 않은 채 크기만 제한하려면 SizedBox를 사용하는 것이 좋습니다.
Padding 문서: https://api.flutter.dev/flutter/widgets/Padding-class.html
어떤 위젯에 padding을 넣을 때 사용합니다.
몇몇 위젯의 경우에는 위젯 내에 padding 필드가 존재하기도 합니다. (Container 위젯의 경우는 decoration을 추가했을 때 padding 영역까지 decoration이 적용되면서 Padding 위젯을 직접 사용할 때와 결과가 달라집니다.)
GestureDetector 문서: https://api.flutter.dev/flutter/widgets/GestureDetector-class.html
모든 위젯에 제스처(터치) 동작을 추가해주는 위젯
보통 터치 영역을 특정 위젯으로 잡아줄 때 많이 사용했습니다. (대표적으로 버튼 동작)
onTap, onDoubleTap, onLongPress 등 다양한 터치 동작에 대해 인식할 때 동작하는 코드를 작성할 수 있습니다.
Dialog 문서: https://api.flutter.dev/flutter/material/Dialog-class.html
팝업 알림창을 띄울 때 대표적으로 사용하는 위젯
다이얼로그를 띄우기 위해선 context 인스턴스가 무조건 필요하다.
showDialog 메서드를 기본으로 사용하여 Dialog 위젯을 화면에 띄웁니다.
void showTransparentDialog(BuildContext context, Widget child, {FutureOr Function(Object? value)? onValue}) {
showGeneralDialog(
context: context,
barrierLabel: '',
barrierDismissible: true,
barrierColor: Colors.white.withOpacity(0), // Colors.transparent로 입력하면 완벽한 투명이 되지 않는다.
pageBuilder: (context, _, __) {
return Material(
type: MaterialType.transparency,
child: child,
);
},
).then(onValue ?? (_) => {});
}