본문 바로가기
50 year old flutter developer challenge

[50살에 플러터 개발 도전기] Study Duck : Drawer 애니메이션으로 화이트노이즈 컨트롤의 UX 개선하기

by Maccrey Coding 2025. 4. 20.
반응형

문제 발견

키워드: Flutter Drawer, UX 개선, 애니메이션 UI, 화이트노이즈 앱, 사용자 경험

Study Duck은 화이트노이즈를 통해 사용자의 집중력을 높여주는 앱입니다.

초기 버전에서는 화이트노이즈 컨트롤을 Drawer에 구현했지만, 햄버거 메뉴를 제거한 탓에 많은 사용자가 Drawer의 존재 자체를 인지하지 못했습니다.

이는 UI/UX 측면에서 실패로 이어졌습니다.

이를 해결하기 위해 Drawer에 애니메이션을 추가해 사용자가 직관적으로 Drawer를 발견할 수 있도록 개선한 과정을 이 블로그에서 공유합니다.

문제 분석

키워드: Drawer UX, 사용자 인터랙션, Flutter UI 디자인

  • 문제점: 햄버거 메뉴를 제거해 화면은 깔끔해졌지만, 사용자가 Drawer를 열 수 있다는 사실을 알지 못함.
  • 원인: Drawer를 여는 스와이프 제스처에 대한 시각적 힌트 부족.
  • 목표: 애니메이션을 통해 Drawer의 존재를 자연스럽게 알리고, 직관적인 UX 제공.

해결 방안: 애니메이션 힌트 추가

키워드: Flutter 애니메이션, Drawer 힌트, 제스처 기반 UI, UX 최적화

사용자가 Drawer를 쉽게 발견할 수 있도록 화면 왼쪽 가장자리에 부드러운 그라데이션 애니메이션을 추가했습니다. 이 애니메이션은 주기적으로 페이드 인/아웃되며, 스와이프 가능 영역을 시각적으로 강조합니다.

1. 애니메이션 컨트롤러 설정

Drawer의 힌트를 주기적으로 표시하기 위해 AnimationController를 사용했습니다. 아래는 애니메이션 로직의 핵심 코드입니다.

class DrawerHint extends StatefulWidget {
  @override
  _DrawerHintState createState() => _DrawerHintState();
}

class _DrawerHintState extends State<DrawerHint> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _opacityAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    )..repeat(reverse: true);

    _opacityAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
      CurvedAnimation(parent: _controller, curve: Curves.easeInOut),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _opacityAnimation,
      builder: (context, child) {
        return Container(
          width: 20.0,
          decoration: BoxDecoration(
            gradient: LinearGradient(
              colors: [
                Colors.white.withOpacity(0.0),
                Colors.white.withOpacity(0.5 * _opacityAnimation.value),
                Colors.white.withOpacity(0.0),
              ],
            ),
          ),
        );
      },
    );
  }
}
  • 설명:
    • AnimationController는 2초 주기로 애니메이션을 반복하며, Curves.easeInOut으로 부드러운 전환을 구현.
    • AnimatedBuilder를 사용해 불필요한 위젯 리빌드를 방지.
    • 그라데이션은 투명도(opacity)를 조절해 자연스러운 페이드 효과를 제공.

2. Scaffold에 Drawer와 힌트 통합

Drawer와 애니메이션 힌트를 앱에 통합하기 위해 ScaffoldStack을 사용했습니다.

Scaffold(
  drawerEdgeDragWidth: 40.0, // 스와이프 영역 설정
  drawerScrimColor: Colors.black.withOpacity(0.7), // Drawer 열릴 때 배경 투명도
  drawer: CustomDrawer(), // 화이트노이즈 컨트롤 Drawer
  body: Stack(
    children: [
      MainContent(), // 메인 콘텐츠
      Positioned(
        left: 0,
        top: 0,
        bottom: 0,
        child: DrawerHint(), // 애니메이션 힌트
      ),
    ],
  ),
)
  • 설명:
    • drawerEdgeDragWidth를 40.0으로 설정해 스와이프 영역을 넓게 확보.
    • Positioned를 사용해 힌트를 화면 왼쪽에 고정.
    • CustomDrawer는 화이트노이즈 볼륨 조절, 소리 선택 등의 기능을 포함.

3. 사용자 피드백 반영

키워드: 사용자 테스트, UI 피드백, Flutter 앱 개선

애니메이션을 추가한 후 소규모 사용자 테스트를 진행했습니다.

  • 피드백:
    • 80% 이상의 사용자가 애니메이션 덕분에 Drawer를 자연스럽게 발견.
    • 일부 사용자는 애니메이션이 너무 빠르다고 느낌.
  • 개선: 애니메이션 주기를 2초에서 3초로 늘리고, 투명도 최대값을 0.5에서 0.4로 낮춰 덜 산만하게 조정.
_controller = AnimationController(
  duration: const Duration(seconds: 3), // 주기 변경
  vsync: this,
)..repeat(reverse: true);

_opacityAnimation = Tween<double>(begin: 0.0, end: 0.4).animate( // 투명도 조정
  CurvedAnimation(parent: _controller, curve: Curves.easeInOut),
);

결과 및 장점

키워드: UX 성공 사례, Flutter Drawer 개선, 사용자 만족도

  • 성과:
    • Drawer 사용률이 30%에서 85%로 증가.
    • 사용자 리뷰에서 "컨트롤이 직관적이다"는 긍정적 피드백 증가.
  • 장점:
    • 직관성: 애니메이션 힌트로 사용자가 스와이프 제스처를 쉽게 학습.
    • 깔끔한 UI: 햄버거 메뉴 없이도 깔끔한 디자인 유지.
    • 모던한 UX: 제스처 기반 인터랙션으로 최신 트렌드 부합.

구현 시 주의사항

키워드: Flutter 개발 팁, UI 디자인 주의사항

  1. 애니메이션 균형: 너무 강한 애니메이션은 사용자를 산만하게 할 수 있으므로 투명도와 주기를 신중히 조정.
  2. 성능 최적화: AnimatedBuilder를 사용해 불필요한 리빌드를 방지.
  3. 튜토리얼 제공: 첫 사용자를 위해 온보딩 화면에 스와이프 제스처를 안내하는 짧은 가이드를 추가 고려.

UX는 세심한 배려에서 시작된다

키워드: Flutter UX, 앱 개발 성공, 사용자 중심 디자인

Study Duck의 Drawer 개선 과정은 사용자 피드백을 반영하고, 세심한 UI 조정을 통해 UX를 향상시킨 사례입니다. 애니메이션 하나로 사용자가 앱을 더 쉽게 이해하고, 더 즐겁게 사용할 수 있게 되었습니다. Flutter 개발자로서, 이 경험은 기술뿐 아니라 사용자의 관점을 이해하는 것이 얼마나 중요한지 다시금 깨닫게 해주었습니다.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawerEdgeDragWidth: 40.0,
      drawerScrimColor: Colors.black.withOpacity(0.7),
      drawer: CustomDrawer(),
      body: Stack(
        children: [
          MainContent(),
          Positioned(left: 0, top: 0, bottom: 0, child: DrawerHint()),
        ],
      ),
    );
  }
}

class MainContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(child: Text('Study Duck: 화이트노이즈 앱'));
  }
}

class CustomDrawer extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: ListView(
        children: [
          ListTile(title: Text('소리 선택')),
          ListTile(title: Text('볼륨 조절')),
        ],
      ),
    );
  }
}

class DrawerHint extends StatefulWidget {
  @override
  _DrawerHintState createState() => _DrawerHintState();
}

class _DrawerHintState extends State<DrawerHint> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _opacityAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 3),
      vsync: this,
    )..repeat(reverse: true);
    _opacityAnimation = Tween<double>(begin: 0.0, end: 0.4).animate(
      CurvedAnimation(parent: _controller, curve: Curves.easeInOut),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _opacityAnimation,
      builder: (context, child) {
        return Container(
          width: 20.0,
          decoration: BoxDecoration(
            gradient: LinearGradient(
              colors: [
                Colors.white.withOpacity(0.0),
                Colors.white.withOpacity(0.5 * _opacityAnimation.value),
                Colors.white.withOpacity(0.0),
              ],
            ),
          ),
        );
      },
    );
  }
}

 

"당신의 학습 스타일에 맞춘 효율적인 학습, Study Duck과 함께하세요!"

MBTI에 따라 맞춤형 학습법을 적용하면, 학습 효과가 두 배로! 혼자 학습하면 빠르게 배울 수 있지만, Study Duck은 꾸준히 장기간 학습을 도와줍니다.
학습 타이머로 집중을 유지하고, 리더보드에서 다른 사람들과 경쟁하며 꾸준함을 유지하세요.
지금 바로 Study Duck으로 학습의 새로운 장을 열어보세요!

www.studyduck.net

 

Study Duck - Smart Learning Assistant

Enhance your study efficiency with personalized MBTI learning strategies, focus mode, and white noise.

studyduck.net

반응형