Flutter轮播图插件marvelous_carousel的使用

发布于 1周前 作者 caililin 来自 Flutter

Flutter轮播图插件marvelous_carousel的使用

简介

Marvelous Carousel 是一个允许用户水平或垂直滚动多个图片或项目的控件。它通常用于需要浏览图片集合或轮播内容的应用程序,例如产品画廊、新闻推送或活动日历。

作者信息

截图

主屏幕

Main Screen
Main Screen

示例截图

Simple Rotation Scale Items
Simple Rotation Scale Items
Opacity Animation Stack Overscroll
Opacity Animation Stack Overscroll

Marvelous Carousel 属性列表

属性名 描述 适用类型
pagerType 设置 MarvelousSlider 类型,例如 PagerType.CarouselPagerType.Stack -
reverse 如果设置为 true 则反转顺序 Both
scrollDirection 滚动方向,例如 Axis.HorizontalAxis.Vertical Both
viewPortFraction 设置视口比例 Carousel
pageSnapping 是否锁定到选定或当前页面 Both
physics 定义 ScrollPhysics,影响滚动速度等 Both
onPageChanged 当选择项目时返回当前索引的回调 Both
scaleX 未选中页面的最小 x 缩放值 Both
scaleY 未选中页面的最小 y 缩放值 Both
opacity 未选中页面的透明度 Both
rotationX 未选中页面的最大 x 旋转值 Carousel
rotationY 未选中页面的最大 y 旋转值 Carousel
overscroll 对最后一个项目应用过度滚动效果 Stack
key 为分页器设置键 Both
children 要添加到分页器中的子控件列表 -
dotsVisible 如果设置为 true 则显示点 -

示例代码

以下是一个完整的示例代码,展示了如何使用 Marvelous Carousel 插件:

import 'package:flutter/material.dart';
import 'package:marvelous_carousel/marvelous_carousel.dart';

void main() => runApp(const EntryWidget());

class EntryWidget extends StatelessWidget {
  const EntryWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Finite Coverflow Example',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        brightness: Brightness.dark,
        splashColor: Colors.transparent,
        highlightColor: Colors.transparent,
      ),
      home: const MyApp(),
    );
  }
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  late final List<Widget> _widgets = [];
  late final List<String> _widgetsTiles = [
    "Simple Carousel",
    "Simple Reverse Carousel",
    "Carousel With Rotation",
    "Scale Items On Change",
    "Opacity Animation On Change",
    "Stack Carousel",
    "Overscroll Stack Carousel",
    "Mixed Animation",
  ];

  late final List<String> _widgetsTilesSubt = [
    "This is just simple carousel. Just attach children and set direction.",
    "Simple Carousel with reverse option. Just Play accordingly.",
    "You can set rotation of carousel items. Visible on page change.",
    "You can set scale of carousel items. Visible on page change.",
    "Opacity Animation of carousel items. It's also visible on change",
    "Stack Carousel animation, Visible on page change.",
    "Overscroll Animation visible on page change",
    "Mixed Animation according to all properties",
  ];

  @override
  void initState() {
    super.initState();
    _widgets.addAll([
      SimpleCarousel(isReverse: false),
      SimpleCarousel(isReverse: true),
      const CarouselWithRotation(),
      const ScaleItemsOnChange(),
      const OpacityAnimationOnChange(),
      const StackCarousel(),
      const OverscrollStackCarousel(),
      const MixedAnimation(),
    ]);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        physics: const ClampingScrollPhysics(),
        child: Column(
          children: [
            Card(
              margin: const EdgeInsets.only(left: 15, right: 15, top: 30, bottom: 100),
              shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
              child: ListView.separated(
                separatorBuilder: (context, index) => const Divider(height: 5),
                shrinkWrap: true,
                itemCount: _widgets.length,
                itemBuilder: (context, index) => ListTile(
                  contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
                  title: Text(_widgetsTiles[index], style: const TextStyle(fontWeight: FontWeight.bold)),
                  trailing: const Icon(Icons.arrow_forward),
                  subtitle: Text(_widgetsTilesSubt[index], style: const TextStyle(height: 1.5)),
                  horizontalTitleGap: 20,
                  onTap: () {
                    Navigator.push(
                      context,
                      MaterialPageRoute(builder: (context) => _widgets[index]),
                    );
                  },
                ),
                padding: EdgeInsets.zero,
                physics: const NeverScrollableScrollPhysics(),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class MixedAnimation extends StatelessWidget {
  const MixedAnimation({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Mixed Animation")),
      body: Center(
        child: SizedBox(
          height: 566,
          child: MarvelousCarousel(
            opacity: 0.2,
            scaleX: 0.5,
            scaleY: 0.5,
            overscroll: 0,
            margin: 10,
            reverse: true,
            pagerType: PagerType.stack,
            scrollDirection: Axis.horizontal,
            children: [1, 2, 3, 4, 5]
                .map(
                  (e) => Card(
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(15),
                      child: SizedBox(
                        height: 566,
                        width: 382,
                        child: Image.asset("images/marvel$e.jpeg", fit: BoxFit.cover),
                      ),
                    ),
                  ),
                )
                .toList(),
          ),
        ),
      ),
    );
  }
}

class OverscrollStackCarousel extends StatelessWidget {
  const OverscrollStackCarousel({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Overscroll Stack Animation")),
      body: Center(
        child: SizedBox(
          height: 566,
          child: MarvelousCarousel(
            overscroll: -300,
            opacity: 0,
            margin: 20,
            pagerType: PagerType.stack,
            dotsVisible: true,
            scrollDirection: Axis.horizontal,
            children: [1, 2, 3, 4, 5]
                .map(
                  (e) => Card(
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(15),
                      child: SizedBox(
                        height: 566,
                        width: 382,
                        child: Image.asset("images/marvel$e.jpeg", fit: BoxFit.cover),
                      ),
                    ),
                  ),
                )
                .toList(),
          ),
        ),
      ),
    );
  }
}

class StackCarousel extends StatefulWidget {
  const StackCarousel({super.key});

  @override
  State<StackCarousel> createState() => _StackCarouselState();
}

class _StackCarouselState extends State<StackCarousel> {
  bool _isVertical = true;
  bool _isReverse = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Stack Carousel")),
      body: Center(
        child: SizedBox(
          height: 566,
          child: MarvelousCarousel(
            pagerType: PagerType.stack,
            margin: 15,
            reverse: _isReverse,
            scrollDirection: _isVertical ? Axis.vertical : Axis.horizontal,
            children: [1, 2, 3, 4, 5]
                .map(
                  (e) => Card(
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(15),
                      child: SizedBox(
                        height: 566,
                        width: 382,
                        child: Image.asset("images/marvel$e.jpeg", fit: BoxFit.cover),
                      ),
                    ),
                  ),
                )
                .toList(),
          ),
        ),
      ),
      bottomNavigationBar: SizedBox(
        height: 90,
        child: Card(
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Text("Vertical", style: TextStyle(fontWeight: FontWeight.w700, fontSize: 15)),
              Switch(
                value: _isVertical,
                thumbColor: const MaterialStatePropertyAll<Color>(Colors.black),
                onChanged: (bool value) {
                  setState(() {
                    _isVertical = value;
                  });
                },
              ),
              Container(color: Colors.grey, width: 1, height: 30),
              const SizedBox(width: 10),
              const Text("Reverse", style: TextStyle(fontWeight: FontWeight.w700, fontSize: 15)),
              Switch(
                value: _isReverse,
                thumbColor: const MaterialStatePropertyAll<Color>(Colors.black),
                onChanged: (bool value) {
                  setState(() {
                    _isReverse = value;
                  });
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class OpacityAnimationOnChange extends StatelessWidget {
  const OpacityAnimationOnChange({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Opacity Animation On Change")),
      body: Center(
        child: SizedBox(
          height: 566,
          child: MarvelousCarousel(
            opacity: 0.25,
            margin: 10,
            scrollDirection: Axis.horizontal,
            children: [1, 2, 3, 4, 5]
                .map(
                  (e) => Card(
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(15),
                      child: SizedBox(
                        height: 566,
                        width: 382,
                        child: Image.asset("images/marvel$e.jpeg", fit: BoxFit.cover),
                      ),
                    ),
                  ),
                )
                .toList(),
          ),
        ),
      ),
    );
  }
}

class ScaleItemsOnChange extends StatelessWidget {
  const ScaleItemsOnChange({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Scale Items On Change")),
      body: Center(
        child: SizedBox(
          height: 566,
          child: MarvelousCarousel(
            scaleX: 0.8,
            scaleY: 0.4,
            margin: 10,
            scrollDirection: Axis.horizontal,
            children: [1, 2, 3, 4, 5]
                .map(
                  (e) => Card(
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(15),
                      child: SizedBox(
                        height: 566,
                        width: 382,
                        child: Image.asset("images/marvel$e.jpeg", fit: BoxFit.cover),
                      ),
                    ),
                  ),
                )
                .toList(),
          ),
        ),
      ),
    );
  }
}

class CarouselWithRotation extends StatelessWidget {
  const CarouselWithRotation({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Carousel With Rotation")),
      body: Center(
        child: SizedBox(
          height: 566,
          child: MarvelousCarousel(
            rotationY: 60,
            margin: 0,
            scrollDirection: Axis.horizontal,
            children: [1, 2, 3, 4, 5]
                .map(
                  (e) => Card(
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(15),
                      child: SizedBox(
                        height: 566,
                        width: 382,
                        child: Image.asset("images/marvel$e.jpeg", fit: BoxFit.cover),
                      ),
                    ),
                  ),
                )
                .toList(),
          ),
        ),
      ),
    );
  }
}

class SimpleCarousel extends StatefulWidget {
  bool isReverse;
  SimpleCarousel({super.key, required this.isReverse});

  @override
  State<SimpleCarousel> createState() => _SimpleCarouselState();
}

class _SimpleCarouselState extends State<SimpleCarousel> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Simple${widget.isReverse ? " Reverse " : " "}Carousel")),
      body: Center(
        child: SizedBox(
          height: 566,
          child: MarvelousCarousel(
            scrollDirection: Axis.horizontal,
            reverse: widget.isReverse,
            margin: 10,
            children: [1, 2, 3, 4, 5]
                .map(
                  (e) => Card(
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(15),
                      child: SizedBox(
                        height: 566,
                        width: 382,
                        child: Image.asset("images/marvel$e.jpeg", fit: BoxFit.cover),
                      ),
                    ),
                  ),
                )
                .toList(),
          ),
        ),
      ),
      bottomNavigationBar: SizedBox(
        height: 90,
        child: Card(
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Text("Reverse", style: TextStyle(fontWeight: FontWeight.w700, fontSize: 15)),
              Switch(
                value: widget.isReverse,
                thumbColor: const MaterialStatePropertyAll<Color>(Colors.black),
                onChanged: (bool value) {
                  setState(() {
                    widget.isReverse = value;
                  });
                },
              ),
              const SizedBox(height: 40),
            ],
          ),
        ),
      ),
    );
  }
}

final Movie testMovie = Movie(
  bannerUrl: 'images/banner.webp',
  posterUrl: 'images/bannerprofile.jpeg',
  title: 'Marvelous Carousel',
  categories: ['Simple', 'Easy', 'Ready to Use'],
);

以上代码展示了如何使用 Marvelous Carousel 插件创建不同类型的轮播图,包括简单的轮播图、带旋转效果的轮播图、缩放效果的轮播图、透明度动画效果的轮播图、堆叠效果的轮播图、过度滚动效果的轮播图以及混合动画效果的轮播图。希望这些示例能帮助你更好地理解和使用 Marvelous Carousel 插件。


更多关于Flutter轮播图插件marvelous_carousel的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter轮播图插件marvelous_carousel的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用Flutter中的marvelous_carousel插件来创建轮播图的代码案例。这个插件允许你创建高度可定制的轮播图,支持多种布局和动画效果。

首先,确保你的Flutter项目中已经添加了marvelous_carousel依赖。你可以在pubspec.yaml文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  marvelous_carousel: ^latest_version  # 请使用最新版本号替换latest_version

然后运行flutter pub get来安装依赖。

以下是一个完整的示例代码,展示了如何使用marvelous_carousel来创建一个简单的轮播图:

import 'package:flutter/material.dart';
import 'package:marvelous_carousel/marvelous_carousel.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Marvelous Carousel Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final List<String> images = [
    'https://example.com/image1.jpg',
    'https://example.com/image2.jpg',
    'https://example.com/image3.jpg',
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Marvelous Carousel Example'),
      ),
      body: Center(
        child: MarvelousCarousel(
          width: double.infinity,
          height: 300,
          viewportFraction: 0.8,
          autoPlay: true,
          autoPlayInterval: 3000,
          autoPlayAnimationDuration: 800,
          autoPlayCurve: Curves.easeInOutQuad,
          enlargeCenterPage: true,
          showIndicators: true,
          indicatorPadding: 12,
          indicatorColor: Colors.white,
          indicatorActiveColor: Colors.blue,
          indicatorShape: BoxShape.circle,
          borderRadius: 16,
          pages: images.map((url) {
            return GestureDetector(
              onTap: () {
                // Handle image tap if needed
              },
              child: Container(
                decoration: BoxDecoration(
                  image: DecorationImage(
                    image: NetworkImage(url),
                    fit: BoxFit.cover,
                  ),
                  borderRadius: BorderRadius.circular(16),
                ),
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}

代码说明:

  1. 依赖添加

    • pubspec.yaml中添加marvelous_carousel依赖。
  2. 主应用

    • MyApp是一个基本的Flutter应用,它包含了一个主题和MyHomePage作为主页。
  3. 主页

    • MyHomePage是一个无状态组件,它包含了一个轮播图。
    • images列表包含了轮播图中要显示的图片URL。
  4. 轮播图配置

    • MarvelousCarousel组件配置了轮播图的各种属性,如宽度、高度、视口比例、自动播放、动画持续时间等。
    • pages属性接收一个图片列表,每个图片被包裹在一个GestureDetector中以便处理点击事件(尽管这里未实现点击处理逻辑)。
  5. 图片显示

    • 每张图片被包裹在一个Container中,并设置了BoxDecoration来加载和显示网络图片。

这个示例展示了如何使用marvelous_carousel来创建一个基本的轮播图,你可以根据需要进一步自定义和扩展它。

回到顶部