Flutter:carousel_slider 横向轮播图、垂直轮播公告栏实现
安装依赖
carousel_slider: ^5.0.0
1、垂直滚动公告栏
import 'package:carousel_slider/carousel_options.dart';
// 垂直滚动公告栏
Widget _buildNotice() {
return <Widget>[
<Widget>[
TDImage(
assetUrl: "assets/img/home11.png",
width: 60.w,
height: 60.w,
),
SizedBox(width: 20.w,),
// 可垂直滚动的公告内容
SizedBox(
width: 490.w,
height: 80.w,
child: CarouselSlider(
items: controller.notices.map((notice) {
return TextWidget.body(
notice,
size: 24.sp,
maxLines: 1,
overflow: TextOverflow.ellipsis,
);
}).toList(),
options: CarouselOptions(
scrollDirection: Axis.vertical, // 垂直方向滚动
height: 80.w, // 设置高度为文字高度
viewportFraction: 1.0, // 每个item占满整个viewport
autoPlay: true, // 自动播放
autoPlayInterval: const Duration(seconds: 3), // 播放间隔
autoPlayAnimationDuration: const Duration(milliseconds: 800), // 动画时长
autoPlayCurve: Curves.easeInOut, // 动画曲线
pauseAutoPlayOnTouch: true, // 触摸时暂停自动播放
enableInfiniteScroll: true, // 无限滚动
),
),
),
SizedBox(width: 40.w,),
TDImage(
assetUrl: "assets/img/home12.png",
width: 28.w,
height: 28.w,
).onTap(()=>Get.toNamed('/notice_list_page')),
].toRow(mainAxisAlignment: MainAxisAlignment.start)
.paddingHorizontal(20.w)
.card(color: const Color(0xffFFF9ED))
.tight(width: 690.w,height: 80.w)
].toRow()
.card(shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0)))
.height(80.w);
}
final List<String> notices = [
'这是第一条公告信息',
'这是第二条公告信息',
'这是第三条公告信息',
];
2、横向轮播图
// 横向轮播图
Widget _buildBanner() {
return <Widget>[
SizedBox(
width: 750.w,
height: 750.w,
child: CarouselSlider(
items: [
TDImage(
assetUrl: 'assets/img/goods.jpg',
width: 750.w,
height: 750.w,
type: TDImageType.square,
),
TDImage(
assetUrl: 'assets/img/goods.jpg',
width: 750.w,
height: 750.w,
type: TDImageType.square,
),
TDImage(
assetUrl: 'assets/img/goods.jpg',
width: 750.w,
height: 750.w,
type: TDImageType.square,
),
],
options: CarouselOptions(
scrollDirection: Axis.horizontal, // 垂直方向滚动
height: 750.w, // 设置高度为文字高度
viewportFraction: 1.0, // 每个item占满整个viewport
autoPlay: true, // 自动播放
autoPlayInterval: const Duration(seconds: 3), // 播放间隔
autoPlayAnimationDuration: const Duration(milliseconds: 800), // 动画时长
autoPlayCurve: Curves.easeInOut, // 动画曲线
pauseAutoPlayOnTouch: true, // 触摸时暂停自动播放
enableInfiniteScroll: true, // 无限滚动
onPageChanged: controller.onPageChanged,
),
),
),
SliderIndicatorWidget(length: 3, currentIndex: controller.currentIndex,color: AppTheme.colorfff,)
.positioned(bottom: 30.w,left: 0,right: 0,),
].toStack().height(750.w);
}
// 页码
int currentIndex = 0;
// 切换页码
void onPageChanged(int index, CarouselPageChangedReason reason) {
currentIndex = index;
update(["goods_detail"]);
}
SliderIndicatorWidget 页码组件
import 'package:chenyanzhenxuan/common/index.dart';
import 'package:flutter/material.dart';
/// slider indicator 指示器
class SliderIndicatorWidget extends StatelessWidget {
/// 个数
final int length;
/// 当前位置
final int currentIndex;
/// 颜色
final Color? color;
/// 是否原型
final bool isCircle;
/// 对齐方式
final MainAxisAlignment alignment;
const SliderIndicatorWidget({
super.key,
required this.length,
required this.currentIndex,
this.color,
this.isCircle = false,
this.alignment = MainAxisAlignment.center,
});
@override
Widget build(BuildContext context) {
Color boxColor = color ?? AppTheme.error;
return Row(
mainAxisAlignment: alignment,
// 采用 list.generate 方式生成 item 项
children: List.generate(length, (index) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 3),
// 圆型宽度 6 , 否则当前位置 15 , 其他位置 8
width: !isCircle
? currentIndex == index
? 15.0
: 8
: 6,
// 圆型高度 6 , 否则 4
height: !isCircle ? 4 : 6,
decoration: BoxDecoration(
// 圆角 4
borderRadius: const BorderRadius.all(Radius.circular(4)),
// 非当前位置透明度 0.3
color: currentIndex == index ? boxColor : boxColor.withOpacity(0.3),
),
);
}),
);
}
}