승상의 코딩 블로그

[Flutter] 이미지 슬라이더 구현 (carousel slider) 본문

Flutter (플러터)

[Flutter] 이미지 슬라이더 구현 (carousel slider)

양승상 2023. 8. 5. 17:17
반응형

image slider

carousel_slider 를 통해서 위의 효과를 쉽게 구현할 수 있습니다.

설치

https://pub.dev/packages/carousel_slider

 

carousel_slider | Flutter Package

A carousel slider widget, support infinite scroll and custom child widget.

pub.dev

# 아래의 명령어로 설치해줍니다.
> flutter pub add carousel_slider

구현 해야하는 것

슬라이드 구현 방식 (저는 좌측으로 구현하고자 함)

이미지를 슬라이드하고 싶다면, 사용자가 슬라이드 할 수 있도록 생각하게 만들어야 합니다.

슬라이드 할 수 있는 화면임을 인지시키는데 2가지 방법을 생각했습니다.

  • 이미지 전체를 화면에 채우고 슬라이드 되는 화면임을 알수 있게 하는 Indicator 를 추가한다.
  • 슬라이드되는 다음 이미지를 보여준다.

이미지가 꽉찬 이미지를 사용하고 싶었기 때문에 Indicator 를 활용한 좌측 이미지로 사용하기로 했습니다.

구현

"사진을 슬라이드하는 화면"과 "Indicator" 2개를 구현하면 됩니다. 

저는 화면 위에 Indicator 가 있었으면 했기 때문에 Stack 위젯도 함께 사용하였습니다.

// Indicator 가 가르켜야하는 Index 에 대한 변수
int activeIndex = 0;
...
@override
Widget build(BuildContext context) {
    double screenHeight = MediaQuery.of(context).size.height; // 화면의 높이
    
    //slider 화면 위에 indicator 가 존재해야하므로 Stack 위젯을 사용합니다.
    return Stack( 
        children: [
            slider(images, screenHeight / 2),
            Positioned.fill(
				//slider 의 높이를 Stack 의 크기만큼 늘려주기 위해서 Positioned.fill 사용함
				child: Align(
                alignment: Alignment.bottomCenter, // 하단 가운데 정렬
                child: indicator(images),
              ),
           ),
        ],
    );
}
...

// 사진을 슬라이드하는 화면
Widget slider(images, height) => CarouselSlider(
        items: images,
        options: CarouselOptions(
          height: height, // height 와 viewportFraction 을 기준으로 이미지의 크기가 설정됨.
          autoPlay: false,
          viewportFraction: 1, // 각 페이지가 차지하는 viewport의 정도임. 0.8로 설정하면 Indicator 가 없는 슬라이드 구성가능함. 
          enlargeCenterPage: true, // 이미지보다 화면이 클 수 있는지 설정
          initialPage: 0, // 초기 페이지 인덱스
          onPageChanged: (index, reason) => setState(() {
            activeIndex = index; // 페이지가 변경될 때, indicator 의 인덱스를 변경함.
          }),
        ),
      );

// Indicator
Widget indicator(images) => Container(
  margin: const EdgeInsets.only(bottom: 20.0),
  alignment: Alignment.bottomCenter,
  child: AnimatedSmoothIndicator(
    activeIndex: activeIndex,
    count: images.length,
    effect: JumpingDotEffect(
        dotHeight: 6,
        dotWidth: 6,
        activeDotColor: Colors.white,
        dotColor: Colors.white.withOpacity(0.6)),
  ));
반응형
Comments