[flutter] 플러터 sticky 헤더를 사용한 워크아웃 트래커 앱 만들기

이번 블로그 포스트에서는 플러터(Flutter)의 sticky 헤더를 사용하여 워크아웃 트래커 앱을 만드는 방법에 대해 알아보겠습니다.

목차

  1. 개요
  2. 필요한 패키지 가져오기
  3. 데이터 모델링
  4. 화면 구성
  5. 스크롤 이벤트 처리
  6. 요약

1. 개요

워크아웃 트래커 앱은 사용자가 운동 기록을 추적하고 저장하는 앱입니다. 이 앱에서는 sticky 헤더를 사용하여 섹션 헤더와 해당 섹션의 운동 기록 카드를 구현할 것입니다.

2. 필요한 패키지 가져오기

프로젝트를 시작하기 전에 flutter_sticky_header 패키지를 가져와야 합니다. 이 패키지는 sticky 헤더를 구현하는 데 사용됩니다. pubspec.yaml 파일에서 다음과 같이 패키지를 추가합니다.

dependencies:
  flutter_sticky_header: ^0.5.3

3. 데이터 모델링

워크아웃 기록을 저장하기 위해 Workout 클래스를 만들어야 합니다. Workout 클래스는 운동 이름, 날짜, 시간, 운동 내용 등의 정보를 포함해야 합니다.

class Workout {
  final String name;
  final DateTime date;
  final String time;
  final String description;

  Workout({
    required this.name,
    required this.date,
    required this.time,
    required this.description,
  });
}

4. 화면 구성

이제 앱의 화면을 구성해보겠습니다. ListView.builder를 사용하여 섹션 헤더와 운동 기록 카드를 동적으로 생성할 수 있습니다. 아래의 코드는 화면을 생성하는 코드입니다.

class WorkoutTrackerApp extends StatelessWidget {
  final List<Workout> workouts;

  const WorkoutTrackerApp({required this.workouts});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Workout Tracker'),
      ),
      body: ListView.builder(
        itemCount: workouts.length,
        itemBuilder: (BuildContext context, int index) {
          final workout = workouts[index];

          // 섹션 헤더 생성
          final header = StickyHeader(
            header: Container(
              height: 50,
              color: Colors.grey[200],
              padding: EdgeInsets.symmetric(horizontal: 16),
              alignment: Alignment.centerLeft,
              child: Text(
                workout.date.toString(), // 날짜를 헤더에 표시
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
            content: Container(), // 매칭되는 운동 기록 카드는 없음
          );

          // 운동 기록 카드 생성
          final card = Card(
            child: ListTile(
              title: Text(workout.name),
              subtitle: Text(workout.time),
              trailing: Icon(Icons.arrow_forward_ios),
              onTap: () {
                // 클릭 이벤트 처리
              },
            ),
          );

          // 섹션 헤더와 운동 기록 카드 반환
          return Column(
            children: [
              header,
              card,
            ],
          );
        },
      ),
    );
  }
}

5. 스크롤 이벤트 처리

이제 스크롤 이벤트를 처리하여 sticky 헤더가 동작하도록 만들어보겠습니다. ScrollController를 사용하여 현재 스크롤 위치를 추적하고, sticky 헤더의 위치를 업데이트합니다.

class WorkoutTrackerApp extends StatefulWidget {
  final List<Workout> workouts;

  const WorkoutTrackerApp({required this.workouts});

  @override
  _WorkoutTrackerAppState createState() => _WorkoutTrackerAppState();
}

class _WorkoutTrackerAppState extends State<WorkoutTrackerApp> {
  final ScrollController _scrollController = ScrollController();
  double _headerOpacity = 0;

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(_handleScroll); // 스크롤 이벤트 리스너 등록
  }

  @override
  void dispose() {
    _scrollController.dispose(); // 리스너 해제
    super.dispose();
  }

  void _handleScroll() {
    setState(() {
      _headerOpacity = _scrollController.hasClients &&
              _scrollController.offset >= kToolbarHeight
          ? 1
          : 0;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Opacity(
          opacity: _headerOpacity,
          child: Text('Workout Tracker'),
        ),
      ),
      body: ListView.builder(
        controller: _scrollController,
        itemCount: workouts.length,
        itemBuilder: (BuildContext context, int index) {
          //...
        },
      ),
    );
  }
}

6. 요약

이제 플러터의 sticky 헤더를 사용하여 워크아웃 트래커 앱을 만들어 보았습니다. 해당 앱은 섹션 헤더와 운동 기록 카드를 동적으로 생성하여 사용자의 운동 기록을 편리하게 추적할 수 있습니다.

이 포스트를 통해 플러터의 sticky 헤더를 사용하는 방법을 익혔습니다. 이제 여러분은 이 기능을 활용하여 고유한 앱을 개발할 수 있습니다. 플러터 문서와 예제를 참고하여 더 많은 기능을 적용할 수 있습니다.

참고: