본문 바로가기
Flutter

간단한 캐러셀 만들기

by 시몽 2021. 4. 12.
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        body: Home(),
      ),
    );
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  List images = [
    'https://images.unsplash.com/photo-1617330070571-60434437a26c?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1267&q=80',
    'https://images.unsplash.com/photo-1564276418402-ec12dc900882?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=1350&q=80',
    'https://images.unsplash.com/photo-1497671954146-59a89ff626ff?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=1350&q=80',
    'https://images.unsplash.com/photo-1611095560192-ccc932f617e1?ixid=MXwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1351&q=80',
    'https://images.unsplash.com/photo-1612831819448-f6cae53d3dcf?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=1233&q=80',
    'https://images.unsplash.com/photo-1587614222490-3497ae026130?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=974&q=80',
  ];
  int currentPage = 1;
  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: 1 / 1,
      child: Stack(
        children: [
          PageView.builder(
            controller: PageController(
              initialPage: images.length * 100,
            ),
            itemBuilder: (context, index) {
              return InkWell(
                onTap: () {
                  ScaffoldMessenger.of(context).showSnackBar(buildSnackBar());
                },
                child: Image.network(
                  '${images[index % images.length]}',
                  fit: BoxFit.cover,
                ),
              );
            },
            onPageChanged: (value) {
              setState(() {
                currentPage = value % images.length + 1;
              });
            },
          ),
          Align(
            alignment: Alignment.bottomRight,
            child: Container(
              color: Colors.black.withOpacity(0.5),
              padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 12.0),
              child: Text(
                '$currentPage / ${images.length}',
                style: TextStyle(
                  color: Colors.white,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  SnackBar buildSnackBar() {
    return SnackBar(
      behavior: SnackBarBehavior.floating,
      margin: EdgeInsets.all(16.0),
      duration: Duration(milliseconds: 1500),
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(100.0)),
      ),
      content: Text('캐러셀이 탭되었습니다.'),
    );
  }
}

 

PageView.builder를 활용해 캐러셀을 만들었습니다. AspectRatio로 캐러셀의 비율을 정하고, 인디케이터는 숫자로 표시하였습니다. 캐러셀을 탭 하면 스낵바가 나오게 되어있습니다. 

 

PageView의 PageController내에 initialPage의 경우 0으로 시작하면 처음에 좌측의 캐러셀 화면으로 넘어가지않는 문제가 있어서 양형들의 해결책이 아예 높은 숫자로 시작하는 걸로 해결하더군요. 코드가 조금 지저분할 수 있지만 간단하게 해결되네요.