플러터의 위젯은 React에서 영감을 받은 현대적인 프레임워크를 사용하여 구축되었습니다. 핵심 개념은 사용자의 UI를 위젯으로 구축하는 것입니다. 위젯은 현재의 구성과 상태에 따라 그 뷰가 어떻게 보여야 하는지를 설명합니다. 위젯의 상태가 변하면 위젯은 그 설명을 다시 구축하고, 프레임워크는 이전 설명과의 차이점을 비교하여 하나의 상태에서 다음 상태로 전환하기 위해 기본 렌더 트리에서 필요한 최소한의 변경사항을 결정합니다.
- 플러터의 주요 작동 원리와 그 기반이 되는 핵심 개념
import 'package:flutter/material.dart';
void main() {
// 이 함수는 전달되는 위젯을 애플리케이션의 루트 위젯으로 만들어 준다.
runApp(
// Center 위젯은 자식 위젯을 화면의 중앙에 배치하는 위젯
// Center -> 이 코드에서 Text 위젯이 자식이다.
Center(
// Text 위젯은 화면에 문자열을 표시하는 위젯이다.
// TextDirection - 글자의 방향을 결정합니다.
// ltr - left to right.
child: Text('Hello World', textDirection: TextDirection.ltr),
)
);
}
이 코드는 "Hello, World"라는 텍스트를 화면의 중앙에 표시하는 Flutter 애플리케이션을 생성
💡 runApp() 함수란
runApp() 함수는 Flutter 애플리케이션을 시작하는 데 필수적입니다.
이 함수를 호출하여 주어진 위젯을 애플리케이션의 루트 위젯으로 설정하고,
Flutter 프레임워크와의 초기 연결을 설정합니다.
Text
위젯 Text을 사용하면 애플리케이션 내에서 스타일이 지정된 텍스트를 생성할 수 있습니다.
Container
위젯 Container을 사용하면 직사각형의 시각적 요소를 만들 수 있습니다. 컨테이너는 BoxDecoration배경, 테두리, 그림자 등으로 장식될 수 있습니다. Container에는 여백, 안쪽 여백 및 크기에 대한 제약 조건이 적용될 수도 있습니다. 또한, Container행렬을 사용하여 3차원 공간에서 변환될 수 있습니다.
Row,Column
이러한 플렉스 위젯을 사용하면 가로(Row) 및 세로(Column) 방향 모두에서 유연한 레이아웃을 만들 수 있습니다. 이러한 객체의 디자인은 웹의 Flexbox 레이아웃 모델을 기반으로 합니다.
Stack
선형 방향(수평 또는 수직) 대신 Stack위젯을 사용하면 페인트 순서에 따라 위젯을 서로 포개어 배치할 수 있습니다. Positioned그런 다음 a의 하위 항목에 대한 위젯을 사용하여 Stack스택의 위쪽, 오른쪽, 아래쪽 또는 왼쪽 가장자리를 기준으로 위치를 지정할 수 있습니다. 스택은 웹의 절대 위치 지정 레이아웃 모델을 기반으로 합니다.
import 'package:flutter/material.dart';
// 코드의 시작점
void main() {
runApp(Center(
child: Container(
width: 100,
height: 100,
color: Colors.lightBlue,
),
));
}
화면에 렌더링되는 위젯들 중에 자식을 가질 수 있는 위젯이 있고 그 위젯들은 속성 child, children 속성을 가지고 있다.
import 'package:flutter/material.dart';
// 코드의 시작점
void main() {
runApp(Center(
child: Container(
child: const Center(
child: const Text(
'Hi Flutter',textDirection: TextDirection.ltr,
)
),
width: 100,
height: 100,
color: Colors.lightBlue,
),
));
}
MaterialApp vs CupertinoApp
MaterialApp
import 'package:flutter/cupertino.dart'; // iOS
import 'package:flutter/material.dart'; // Google
void main() => runApp(
MaterialApp(
home: Scaffold(
body: Text('Hi ~ Dart And Flutter'),
),
),
);
디자인 가이드 라인
Material.io
플러터 Doc
Flutter Document
StatelessWidget - 상태 비저장 위젯
StatelessWidget은 변경할 수 없는 정보를 보유하는 위젯입니다. 이 위젯은 한 번 생성되면 변경되지 않습니다.
이 위젯은 주어진 정보를 기반으로 UI를 구성하지만, 그 자체로 내부 상태를 변경하거나 유지하지 않습니다.
// flutter의 Material 라이브러리
import 'package:flutter/material.dart';
// 애플리케이션의 진입점
void main() {
// MyStatelessApp 위젯을 애플리케이션 루트로 설정하고 실행합니다.
runApp(MyStatelessApp());
}
// 단축키 stl
// StatelessWidget 위젯을 상속해서 MystatelessApp 위젯을 정의합니다.
class MyStatelessApp extends StatelessWidget {
// 기본 생성자. {} 선택적 key 인자를 상위 클래스로 전달하고 있다.
const MyStatelessApp({super.key});
// 이 메서드는 위젯을 반환하고 UI 부분을 렌더링, 빌드합니다.
Widget build(BuildContext context) {
return MaterialApp(
// MaterialApp에서 제공하는 레이아웃 구조를 제공합니다.
home: Scaffold(
appBar: AppBar(
title: Text('Widget Example'),
),
body: Center(
child: Text('Hello My App'),
),
),
);
}
}
StatefulWidget은 가변적인 상태를 갖는 위젯을 생성하는 데 사용되는 위젯입니다. 사용자와의 상호 작용이나 시간 경과와 같은 요인에 따라 내부 상태가 변할 수 있는 위젯을 만들 때 사용합니다.
상태 관리: StatefulWidget은 내부 상태를 관리하기 위해 별도의 State 객체를 사용합니다. 이 State 객체는 위젯의 생명 주기 동안 상태를 보존합니다.
생명 주기: StatefulWidget은 생성, 업데이트, 제거 등의 생명 주기가 있습니다. 이 생명 주기는 State 객체 내에서 관리됩니다.
변경 알림: 내부 상태가 변경될 때마다 setState() 메서드를 호출하여 Flutter 프레임워크에 알립니다. 그 결과로 build 메서드가 다시 호출되어 UI를 업데이트합니다.
// flutter의 Material 라이브러리
import 'package:flutter/material.dart';
void main() => runApp(MyStatefulApp());
// 단축키 stf
class MyStatefulApp extends StatefulWidget {
const MyStatefulApp({super.key});
// createState() 메서드는 State 객체를 생성 합니다.
// 즉, State 객체가 있다 --> StatefulWidget 이다.
State<MyStatefulApp> createState() => _MyStatefulAppState();
} // end of MyStatefulApp
class _MyStatefulAppState extends State<MyStatefulApp> {
int _counter = 0;
// 메서드
void _incrementCounter() {
// StatefulWidget과 함께 사용되며 위젯의 상태를 변경하고
// 화면을 다시 그리게 알려 주는 역할 - build() 실행
setState(() {
_counter++;
});
}
Widget build(BuildContext context) {
print('build 메서드 호출 확인');
return MaterialApp(
home: Scaffold(
body: Center(
child: ElevatedButton(
onPressed: _incrementCounter,
child: Text('Count : $_counter'),
),
),
),
);
}
} // end of _MyStatefulApp
Handling gestures
대부분의 애플리케이션들은 시스템과의 어떤 형태의 사용자 상호 작용을 포함하고 있습니다. 상호 작용이 있는 애플리케이션을 구축하는 첫 번째 단계는 입력 제스처를 감지하는 것입니다.
Flutter의 제스처(Gestures) 개념
Flutter에서, 제스처는 사용자의 입력 동작(예: 탭, 드래그, 핀치 등)을 감지하는 데 사용되는 도구입니다. Flutter는 위젯 기반의 제스처 인식 시스템을 제공하며, 이를 통해 다양한 사용자 상호 작용을 쉽게 구현할 수 있습니다.
대표적인 제스처 위젯 및 클래스
Tap
GestureDetector 위젯은 단순한 탭 동작을 감지할 수 있습니다.
Double Tap
두 번 탭하는 동작도 GestureDetector로 감지할 수 있습니다.
Drag
사용자의 드래그 동작을 감지합니다.
Pinch
두 손가락으로 확대/축소하는 제스처입니다.
Long Press
사용자가 화면을 길게 누르는 동작을 감지합니다.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
} // end of MyApp
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Gesture Detector Example'),
),
body: Center(
// GestureDetector 위젯을 사용하여 다양한 제스처를 감지할 수 있습니다.
child: GestureDetector(
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Taped'),
),
);
},
onLongPress: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Long Pressed'),
),
);
},
),
),
);
}
}
Hot Reload:
Hot Restart:
주의 사항: Hot Restart를 실행하면 앱의 모든 상태와 데이터가 초기화됩니다. 따라서 특정 상태에서의 테스트나 디버깅을 진행하고 있었다면, 다시 해당 상태로 돌아가기 위한 작업이 필요합니다