본문 바로가기
Flutter

Flutter로 개발한 앱의 효과적인 사용자 온보딩, 쉽게 쓰게 하기!!

by 난타코다옹 2023. 10. 4.

목차

    Flutter Alarm 앱을 사용하는 사용자들이 앱의 기능을 쉽게 이해하고 사용할 수 있게 해야겠죠?!.

    이번 글에서는 Flutter를 사용하여 Alarm 앱의 효과적인 사용자 온보딩을 구현하는 방법에 대해 알아보겠습니다.

    1. 온보딩 페이지 구현하기
      Flutter에서 온보딩 페이지를 구현하는 방법은 다양합니다. 이번 글에서는 PageView 위젯을 사용하여 온보딩 페이지를 구현해보겠습니다.
    class OnboardingPage extends StatelessWidget {
      final String title;
      final String description;
      final String image;
    
      OnboardingPage({required this.title, required this.description, required this.image});
    
      @override
      Widget build(BuildContext context) {
        return Container(
          padding: EdgeInsets.all(20.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Image.asset(image),
              SizedBox(height: 30.0),
              Text(
                title,
                style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
              ),
              SizedBox(height: 10.0),
              Text(
                description,
                textAlign: TextAlign.center,
                style: TextStyle(fontSize: 16.0),
              ),
            ],
          ),
        );
      }
    }
    
    class OnboardingScreen extends StatefulWidget {
      @override
      _OnboardingScreenState createState() => _OnboardingScreenState();
    }
    
    class _OnboardingScreenState extends State<OnboardingScreen> {
      final PageController _pageController = PageController(initialPage: 0);
      int _currentPage = 0;
    
      List<OnboardingPage> _pages = [
        OnboardingPage(
          title: 'Welcome to Alarm App',
          description: 'Get started by setting up your first alarm',
          image: 'assets/images/onboarding1.png',
        ),
        OnboardingPage(
          title: 'Customize Your Alarms',
          description: 'Choose from a variety of sounds and themes',
          image: 'assets/images/onboarding2.png',
        ),
        OnboardingPage(
          title: 'Never Miss an Alarm',
          description: 'Get reminders and notifications to help you stay on track',
          image: 'assets/images/onboarding3.png',
        ),
      ];
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            children: [
              Expanded(
                child: PageView.builder(
                  controller: _pageController,
                  itemCount: _pages.length,
                  onPageChanged: (int page) {
                    setState(() {
                      _currentPage = page;
                    });
                  },
                  itemBuilder: (BuildContext context, int index) {
                    return _pages[index];
                  },
                ),
              ),
              SizedBox(height: 20.0),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: List.generate(
                  _pages.length,
                  (index) => buildDot(index: index),
                ),
              ),
              SizedBox(height: 20.0),
              ElevatedButton(
                onPressed: () {
                  if (_currentPage == _pages.length - 1) {
                    Navigator.pushReplacementNamed(context, '/home');
                  } else {
                    _pageController.nextPage(
                      duration: Duration(milliseconds: 500),
                      curve: Curves.ease,
                    );
                  }
                },
                child: Text(
                  _currentPage == _pages.length - 1 ? 'Get Started' : 'Next',
                  style: TextStyle(fontSize: 18.0),
                ),
              ),
              SizedBox(height: 20.0),
            ],
          ),
        );
      }
    
      Widget buildDot({required int index}) {
        return AnimatedContainer(
          duration: Duration(milliseconds: 200),
          margin: EdgeInsets.symmetric(horizontal: 5.0),
          height: 10.0,
          width: _currentPage == index ? 20.0 : 10.0,
          decoration: BoxDecoration(
            color: _currentPage == index ? Colors.blue : Colors.grey,
            borderRadius: BorderRadius.circular(5.0),
          ),
        );
      }
    }

    위 코드는 PageView 위젯을 사용하여 온보딩 페이지를 구현한 예제입니다. 사용자는 'Next' 버튼을 눌러 페이지를 넘기거나, 마지막 페이지에서 'Get Started' 버튼을 눌러 앱의 메인 페이지로 이동할 수 있습니다.

    1. SharedPreferences를 사용하여 온보딩 완료 여부 저장하기
      앱을 처음 실행할 때마다 온보딩 페이지를 보여주는 것은 사용자에게 불편을 줄 수 있습니다. 따라서, 사용자가 온보딩을 완료한 후에는 다음 실행 때부터 바로 메인 페이지로 이동할 수 있도록 해야합니다. 이를 위해 SharedPreferences를 사용하여 온보딩 완료 여부를 저장해보겠습니다.
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Alarm App',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: FutureBuilder(
            future: SharedPreferences.getInstance(),
            builder: (BuildContext context, AsyncSnapshot<SharedPreferences> snapshot) {
              if (!snapshot.hasData) {
                return Container(
                  color: Colors.white,
                  child: Center(
                    child: CircularProgressIndicator(),
                  ),
                );
              }
              final SharedPreferences prefs = snapshot.data!;
              final bool showOnboarding = prefs.getBool('showOnboarding') ?? true;
    
              return showOnboarding ? OnboardingScreen() : HomePage();
            },
          ),
          routes: {
            '/home': (BuildContext context) => HomePage(),
          },
        );
      }
    }

    위 코드는 SharedPreferences를 사용하여 온보딩 완료 여부를 저장하고, 다음 실행 때부터는 바로 메인 페이지로 이동하도록 구현한 예제입니다. 사용자가 앱을 처음 실행할 때는 온보딩 페이지를 보여주고, 온보딩을 완료한 후에는 SharedPreferences에 값을 저장하여 다음 실행 때부터는 메인 페이지로 바로 이동하도록 합니다.

     

    app onboarding

    Flutter Alarm 앱에서 사용자 온보딩을 구현하는 방법에 대해 알아보았습니다. 온보딩 페이지를 구현하고, SharedPreferences를 사용하여 온보딩 완료 여부를 저장하여 사용자 경험을 향상시키는 방법을 살펴보았습니다. 이제 여러분도 Flutter 앱에서 효과적인 사용자 온보딩을 구현해보세요!