Flutter:carousel_slider 横向轮播图、垂直轮播公告栏实现

安装依赖

cpp 复制代码
carousel_slider: ^5.0.0

1、垂直滚动公告栏

js 复制代码
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、横向轮播图

js 复制代码
  // 横向轮播图
  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 页码组件

js 复制代码
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),
          ),
        );
      }),
    );
  }
}
相关推荐
恋猫de小郭24 分钟前
Flitz ,一个把 Flutter 玩成热插拔 Preview 的有趣项目,不错的思路
android·前端·flutter
FungLeo28 分钟前
成为全栈·Flutter App 篇·Refresh Token 旋转与并发 401:安全存储与会话代次
flutter·jwt·移动安全·身份认证·token刷新·成为全栈
m0_738185821 小时前
Flutter 鸿蒙化实战:simple_circular_progress_bar 适配 OpenHarmony,环形进度条
flutter·华为·harmonyos·鸿蒙
大龄秃头程序员17 小时前
Riverpod 深度解析:从响应式本质到最小可运行闭环
flutter
曹小强wxx18 小时前
让 AI 写代码不“翻车”:用 Claude Code + Codex 给 Flutter 项目搭一套工程规范
flutter·ai编程·claude
西西学代码21 小时前
像素和颜色之间的转换(Flutter)
前端·javascript·flutter
曹小强wxx1 天前
Flutter 局域网设备发现:UDP 广播 + mDNS 双路合并,以及靠谱的在线判定与断线重连
物联网·网络协议·flutter
FungLeo1 天前
成为全栈·Flutter App 篇·移动端错误与限流:429、重试和写请求边界
flutter·限流·dart·dio·错误处理·成为全栈
恋猫de小郭1 天前
Kotlin Toolchain 0.13,JetBrains 推荐 KMP 都切换到到全新工具链
android·前端·flutter
m0_738185821 天前
Flutter 鸿蒙化实战:rive 适配 OpenHarmony,Rive 动画
flutter·华为·harmonyos·鸿蒙