Flutter轮播图插件marvelous_carousel的使用
Flutter轮播图插件marvelous_carousel的使用
简介
Marvelous Carousel
是一个允许用户水平或垂直滚动多个图片或项目的控件。它通常用于需要浏览图片集合或轮播内容的应用程序,例如产品画廊、新闻推送或活动日历。
作者信息
- Author: Kazım Selman Poyraz
- LinkedIn: Kspoyraz
- GitHub: Kspo
- License: MIT
- Last Commit: GitHub last commit
截图
主屏幕
Main Screen |
---|
示例截图
Simple | Rotation | Scale Items |
---|---|---|
Opacity Animation | Stack | Overscroll |
---|---|---|
Marvelous Carousel 属性列表
属性名 | 描述 | 适用类型 |
---|---|---|
pagerType |
设置 MarvelousSlider 类型,例如 PagerType.Carousel 和 PagerType.Stack |
- |
reverse |
如果设置为 true 则反转顺序 |
Both |
scrollDirection |
滚动方向,例如 Axis.Horizontal 和 Axis.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
更多关于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(),
),
),
);
}
}
代码说明:
-
依赖添加:
- 在
pubspec.yaml
中添加marvelous_carousel
依赖。
- 在
-
主应用:
MyApp
是一个基本的Flutter应用,它包含了一个主题和MyHomePage
作为主页。
-
主页:
MyHomePage
是一个无状态组件,它包含了一个轮播图。images
列表包含了轮播图中要显示的图片URL。
-
轮播图配置:
MarvelousCarousel
组件配置了轮播图的各种属性,如宽度、高度、视口比例、自动播放、动画持续时间等。pages
属性接收一个图片列表,每个图片被包裹在一个GestureDetector
中以便处理点击事件(尽管这里未实现点击处理逻辑)。
-
图片显示:
- 每张图片被包裹在一个
Container
中,并设置了BoxDecoration
来加载和显示网络图片。
- 每张图片被包裹在一个
这个示例展示了如何使用marvelous_carousel
来创建一个基本的轮播图,你可以根据需要进一步自定义和扩展它。