IMCAT.DEV
로그인 가입
Dart 고급 프레임워크

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'),
                ),
              ],
            ),
          ),
        );
      }
    }

    실행 결과

  • 화면 중앙에 'Count: 0'이라는 텍스트와 'Increment' 버튼이 표시됩니다.
  • 버튼을 클릭할 때마다 카운트가 1씩 증가합니다.
  • 코드 설명

    1. main 함수에서 MyApp 위젯을 실행합니다.
    2. MyApp은 MaterialApp을 생성하며, Counter 위젯을 홈으로 설정합니다.
    3. Counter는 Stateful Widget으로, _CounterState를 생성합니다.
    4. _count라는 변수를 선언하고, _increment 함수를 통해 카운트를 증가시킵니다.
    5. build 메서드에서 UI를 구성하고, 버튼 클릭 시 _increment를 호출하여 상태를 업데이트합니다.
    6. 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++;
        });
      }
    7. setState()를 호출하지 않으면 UI가 업데이트되지 않음.
    8. 5.2. Widget 재사용

      잘못된 코드

      @override
      Widget build(BuildContext context) {
        return Container(); // 매번 새로운 위젯을 생성
      }

      올바른 코드

      @override
      Widget build(BuildContext context) {
        return const ReusableWidget(); // 재사용 가능한 위젯 사용
      }
    9. 매번 새로운 위젯을 생성하면 성능 저하가 발생할 수 있음.
    10. 6. 정리

    11. 고급 Flutter UI 구성 기술은 사용자 경험을 향상시키는 데 필수입니다.
    12. Stateful과 Stateless Widget을 이해하고 적절히 사용해야 합니다.
    13. Custom Paint를 통해 복잡한 그래픽을 그릴 수 있습니다.
    14. 실무에서는 장바구니, 대시보드와 같은 다양한 UI 패턴을 활용할 수 있습니다.

다음에 학습하면 좋은 주제는 Flutter의 상태 관리 패턴 (Provider, Bloc 등)입니다. 이를 통해 더 복잡한 상태 관리를 쉽게 할 수 있습니다.