2023.12.04 - [Programming Language/Flutter] - [Dart, Flutter] Carousel Slider 를 이용하여 여러 View를 보이기

 

[Dart, Flutter] Carousel Slider 를 이용하여 여러 View를 보이기

간혹 처음사용하는 App을 켜면 사용방법이 touch & slide 형식으로 이루어져있는 것을 몇번 보았을 것입니다. 저희 프로젝트 App에서도 그러한 기능을 넣기위해서 찾아보다가 Carousel Slider 라는 Package

developepe.tistory.com

 

이전에 작성한 글에서는 Carosel Slider를 이용하여 이미지 또는 View를 슬라이드 하는 형식으로 페이지를 이동했습니다.

이번에는 현재 슬라이드가 어디 슬라이드 인지, 몇번째 슬라이드인지를 알 수 있는 Indicator 위젯을 작성해보겠습니다.

 

Widget sliderIndicator() {
    return Row( // 수평방향의 여러개 위젯을 놓을 수 있는 Row widget
      mainAxisAlignment: MainAxisAlignment.center, // Align 방향을 Center로 잡기
      children: List.generate(widgetList.length, (index) { // WidgetList 의 갯수만큼
        return Container( // Container widget 생성
          width: 8.0, // 가로길이
          height: 8.0, // 세로길이
          margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0), // margin
          decoration: BoxDecoration( // Container를 꾸며줍니다
              shape: BoxShape.circle, // 모양은 원형
              // _current(현재페이지) 변수가 List index와 일치할 때, 
              // blue 색으로 강조, 아닌 것은 grey 색으로.
              color: _current == index ? Colors.blueAccent : Colors.grey),
        );
      }),
    );
  }

 

_current 변수같은 경우, 아래 함수에 의해서 페이지가 이동할때마다 호출되고 내부 setState() 함수를 통해 페이지를 다시 렌더링 한다.

 

void onPageChange(index){
    setState(() {
      _current = index;
    });
  }

 

전체코드는 다음과 같습니다.

사용하기 위해서는 widget list와 일부 Image 경로를 커스터마이징 해주셔야 사용이 가능합니다!

 

import 'package:flutter/material.dart';
import 'package:mapdesign_flutter/LoginPage/introduction_page_2.dart';
import 'package:mapdesign_flutter/LoginPage/introduction_page_3.dart';
import 'package:mapdesign_flutter/LoginPage/login_page.dart';
import 'package:carousel_slider/carousel_controller.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:mapdesign_flutter/LoginPage/introduction_page_1.dart';

class LoginModule extends StatefulWidget {
  const LoginModule({Key? key}) : super(key: key);

  @override
  State<LoginModule> createState() => _LoginModuleState();
}

class _LoginModuleState extends State<LoginModule> {
  final CarouselController _carouselController = CarouselController();
  int _current = 0;
  late List<Widget> widgetList;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    widgetList = [
      // scaffold pages
      IntroductionFirstPage(setLastPage: _setLastPage),
      IntroductionSecondPage(setLastPage: _setLastPage,),
      IntroductionThirdPage(setLastPage: _setLastPage),
      LoginPage(),
    ];
  }
  // skip 버튼을 눌렀을 때 마지막 페이지로 이동
  void _setLastPage(){
    setState(() {
      _current = 3;
    });
    _carouselController.jumpToPage(3);
  }
  void onPageChange(index){
    setState(() {
      _current = index;
    });
  }
  Widget sliderWidget() {
    return CarouselSlider(
      carouselController: _carouselController,
      items: widgetList,
      options: CarouselOptions(
          height: MediaQuery.of(context).size.height,
          autoPlay: false,
          enlargeCenterPage: true,
          viewportFraction: 0.9,
          aspectRatio: 2.0,
          initialPage: 0,
          enableInfiniteScroll: false,
          scrollDirection: Axis.horizontal,
          pageSnapping: true,
          onPageChanged: (index, reason) {
            onPageChange(index);
          }),
    );
  }

  Widget sliderIndicator() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: List.generate(widgetList.length, (index) {
        return Container(
          width: 8.0,
          height: 8.0,
          margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
          decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: _current == index ? Colors.blueAccent : Colors.grey),
        );
      }),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
          image: DecorationImage(
        colorFilter: ColorFilter.mode(
          Colors.black.withOpacity(0.5),
          BlendMode.darken,
        ),
        fit: BoxFit.cover,
        image: AssetImage('asset/flutter_asset/find_path.png'),
      )),
      child: Column(
        children: [
          Expanded(child: sliderWidget()),
          SafeArea(top: false, child: sliderIndicator()),
        ],
      ),
    );
  }
}

 

하단에 Indicator가 있는것을 확인할 수 있다.

 

참고자료:

https://pub.dev/packages/carousel_slider