학습
Dart 고급 Flutter UI 구성
Dart 고급 Flutter UI 구성 — 고급
고급 Flutter UI 구성
1. 도입 (왜 배워야 하는가)
Flutter는 구글이 개발한 UI 툴킷으로, 모바일부터 웹, 데스크탑까지 다양한 플랫폼에서 고품질의 애플리케이션을 만들 수 있게 해줍니다. 고급 Flutter UI 구성 기술을 배우는 것은 특히 복잡한 사용자 인터페이스를 효과적으로 설계하고, 사용자 경험을 극대화하는 데 필수적입니다. 예를 들어, 쇼핑몰 앱에서 사용자에게 매력적인 장바구니 UI를 제공하거나, 대시보드에서 데이터를 시각적으로 표현하는 등의 상황에서 고급 UI 기술이 요구됩니다.
이 기술을 모르면 사용자 인터페이스가 단조롭고 매력적이지 않아 사용자가 앱을 이탈할 가능성이 높아집니다. 또한, 유지보수와 확장성이 떨어져 나중에 기능 추가나 UI 변경이 어려워질 수 있습니다.
2. 핵심 개념 설명
2.1. Stateful Widget vs Stateless Widget
- Stateful Widget: 상태를 가질 수 있는 위젯으로, UI가 변할 수 있습니다.
- Stateless Widget: 상태를 가지지 않으며, 주어진 데이터에 따라 항상 동일한 UI를 반환합니다.
비유하자면, Stateful Widget은 사람의 감정과 같아서 상황에 따라 변할 수 있지만, Stateless Widget은 무표정한 얼굴처럼 항상 같은 모습을 유지합니다.
| 유형 | 특징 | 예시 |
|---|---|---|
| Stateful | 상태 변화에 반응 | 체크박스, 슬라이더 |
| Stateless | 상태 변화 없음 | 텍스트, 아이콘 |
2.2. Custom Paint
Custom Paint는 복잡한 도형이나 그래픽을 그릴 수 있는 위젯입니다. 예를 들어, 특정 패턴이나 애니메이션을 만들 때 유용합니다. 이는 마치 화가가 캔버스에 직접 그림을 그리는 것과 비슷합니다.
3. 기본 코드 예제
아래는 Stateful Widget을 사용하여 카운터 앱을 만드는 기본 코드입니다.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Counter(),
);
}
}
class Counter extends StatefulWidget {
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _count = 0;
void _increment() {
setState(() {
_count++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Counter App")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Count: $_count', style: TextStyle(fontSize: 24)),
ElevatedButton(
onPressed: _increment,
child: Text('Increment'),
),
],
),
),
);
}
}
실행 결과
코드 설명
main함수에서MyApp위젯을 실행합니다.MyApp은 MaterialApp을 생성하며,Counter위젯을 홈으로 설정합니다.Counter는 Stateful Widget으로,_CounterState를 생성합니다._count라는 변수를 선언하고,_increment함수를 통해 카운트를 증가시킵니다.build메서드에서 UI를 구성하고, 버튼 클릭 시_increment를 호출하여 상태를 업데이트합니다.setState()를 호출하지 않으면 UI가 업데이트되지 않음.- 매번 새로운 위젯을 생성하면 성능 저하가 발생할 수 있음.
- 고급 Flutter UI 구성 기술은 사용자 경험을 향상시키는 데 필수입니다.
- Stateful과 Stateless Widget을 이해하고 적절히 사용해야 합니다.
- Custom Paint를 통해 복잡한 그래픽을 그릴 수 있습니다.
- 실무에서는 장바구니, 대시보드와 같은 다양한 UI 패턴을 활용할 수 있습니다.
4. 실전 활용 예제
4.1. 쇼핑몰에서 장바구니를 구현할 때
장바구니 기능은 사용자가 선택한 상품을 담고, 수량이나 삭제 기능이 필요합니다. 아래는 장바구니의 기본 구조입니다.
class CartItem {
final String name;
int quantity;
CartItem(this.name, this.quantity);
}
class Cart extends StatefulWidget {
@override
_CartState createState() => _CartState();
}
class _CartState extends State<Cart> {
List<CartItem> _items = [
CartItem("Apple", 1),
CartItem("Banana", 2),
];
void _addItem(String name) {
setState(() {
_items.add(CartItem(name, 1));
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Cart")),
body: ListView.builder(
itemCount: _items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_items[index].name),
trailing: Text("Qty: ${_items[index].quantity}"),
);
},
),
);
}
}
4.2. 대시보드에서 데이터 시각화할 때
Custom Paint를 사용하여 데이터 차트를 그릴 수 있습니다. 다음은 간단한 원형 차트를 그리는 예제입니다.
class PieChart extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomPaint(
size: Size(200, 200),
painter: PieChartPainter(),
);
}
}
class PieChartPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
double angle = 0; // 시작 각도
final paint = Paint()..style = PaintingStyle.fill;
// 데이터에 따라 원의 일부를 그리는 예시
paint.color = Colors.red;
canvas.drawArc(Rect.fromCircle(center: Offset(size.width / 2, size.height / 2), radius: size.width / 2),
angle, 1.57, true, paint); // 90도
angle += 1.57; // 다음 색으로 이동
paint.color = Colors.blue;
canvas.drawArc(Rect.fromCircle(center: Offset(size.width / 2, size.height / 2), radius: size.width / 2),
angle, 1.57, true, paint); // 90도
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
5. 흔한 실수와 주의사항
5.1. 상태 관리
잘못된 코드
void _increment() {
_count++;
// setState()를 호출하지 않음
}
올바른 코드
void _increment() {
setState(() {
_count++;
});
}
5.2. Widget 재사용
잘못된 코드
@override
Widget build(BuildContext context) {
return Container(); // 매번 새로운 위젯을 생성
}
올바른 코드
@override
Widget build(BuildContext context) {
return const ReusableWidget(); // 재사용 가능한 위젯 사용
}
6. 정리
다음에 학습하면 좋은 주제는 Flutter의 상태 관리 패턴 (Provider, Bloc 등)입니다. 이를 통해 더 복잡한 상태 관리를 쉽게 할 수 있습니다.