Flutter笔记:发布一个多功能轮播组件 awesome_carousel

简介: awesome_carousel 模块是一个Flutter轮播图模块。可以实现包括自定义指示器、动画、滚动等等众多功能。能够指定相当多地细节(可以参考 API 部分了解)本文给出 awesome_carousel 模块的两个简单的用法示例。

Flutter笔记电商中文货币显示插件 Money Display


作者李俊才 (jcLee95)https://blog.csdn.net/qq_28550263

邮箱 :291148484@163.com

本文地址https://blog.csdn.net/qq_28550263/article/details/133814670

项目仓库http://thispage.tech:9680/jclee1995/flutter_money_display.git

English Document:https://github.com/jacklee1995/flutter-carousels/blob/master/README.md


【简介】awesome_carousel 模块是一个Flutter轮播图模块。可以实现包括自定义指示器、动画、滚动等等众多功能。能够指定相当多地细节(可以参考 API 部分了解)。欢迎对本模块贡献代码和后续改进提出功能需求。

本文给出 awesome_carousel 模块的两个简单的用法示例。

这两个示例的效果预览如下:

目 录


1. 从一个现实场景说起

我最近观察淘宝的商品展示轮播,发现不是那么直接,市面上没有找到可以直接套用的轮播组件。其中第一个轮播单元是商品的介绍视频,对应的轮播指示器是视频的进度条,而后续的轮播单元仅仅是轮播图片。比如:

因此我打算自己发布一个通用型模块,用于实现包括自定义指示器、动画、滚动等多功能的轮播插件。

2. 模块安装

flutter pub add awesome_carousel

这将向你的包的 pubspec.yaml 中添加一行(并运行一个隐式的 flutter pub get):

dependencies:
  awesome_carousel: ^1.0.0

改命令始终安装最新版本,随着时间推移版本号可能变化。需要安装指定版本也可以直接编辑 pubspec.yaml 文件后显示地运行 flutter pub get 命令。

3. 入门案例

3.1 入门示例1

本模块(awesome_carousel)提供的 Carousel 组件十分容易实现多种需求场景下的轮播功能,开发者可以定制轮播相关效果和轮播进度指示器。下面是两个使用 Carousel 组件默认的轮播进度指示器的例子:

import 'package:awesome_carousel/carousels.dart';
import 'package:flutter/material.dart';
class WidgetCarouSelDemo extends StatelessWidget {
  const WidgetCarouSelDemo({super.key});
  @override
  Widget build(BuildContext context) {
    final double width = MediaQuery.of(context).size.width;
    final double height = MediaQuery.of(context).size.height;
    final List<Color> colors = [
      Colors.amber,
      Colors.blue,
      Colors.red,
      Colors.green,
      const Color.fromARGB(255, 59, 255, 177),
    ];
    List<Widget> units = [];
    for (var i = 0; i < colors.length; i++) {
      units.add(
        Container(
          width: width,
          height: height,
          decoration: BoxDecoration(
            color: colors[i],
          ),
          child: Center(
            child: Text(
              'Page $i',
              style: const TextStyle(
                fontSize: 46,
                fontWeight: FontWeight.w900,
              ),
            ),
          ),
        ),
      );
    }
    return Column(
      children: [
        Carousel(
          units,
          indicatorShape: BoxShape.circle,
          indicatorWidth: 16,
          currentIndicatorColor: Colors.purple,
        ),
        const Divider(),
        ClipRRect(
          borderRadius: BorderRadius.circular(40.0), // 圆角半径
          child: Carousel(
            units.reversed.toList(),
            scrollDirection: Axis.vertical,
            indicatorShape: BoxShape.rectangle,
            indicatorWidth: 10,
            indicatorHeight: 10,
            currentIndicatorColor: Colors.pink,
            onUnitTapped: (index) => print('轮播单元 $index 被点击了'),
            onIndicatorTapped: (index) => print('进度指示单元 $index 被点击了'),
          ),
        )
      ],
    );
  }
}

其效果如下:

3.2 入门示例2

为了实现更加复杂的功能,需要定义更多的参数,以及使用轮播控制器。下面是一个自定义轮播进度指示器样式,并使用网络图片作为轮播单元的例子。

import 'package:flutter/material.dart';
import 'package:awesome_carousel/carousels.dart';
class NetworkImageCarouselDemo extends StatelessWidget {
  final List<String> imageUrls;
  final CarouselController _controller;
  const NetworkImageCarouselDemo(
    this.imageUrls,
    this._controller, {
    super.key,
  });
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Carousel(
          _buildImages(context),
          height: 400.0, // 设置轮播图高度
          controller: _controller,
          indicatorColor: const Color.fromARGB(255, 190, 255, 130),
          // currentIndicatorColor: Colors.transparent,
          indicatorBuilder: _indicatorBuilder,
          // 当用户点击图像时触发的回调函数
          onUnitTapped: (int index) {
            print('点击了第 $index 张图片');
          },
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () {
                _controller.toFirstPage();
              },
              child: const Text('首页'),
            ),
            const Spacer(
              flex: 1,
            ),
            ElevatedButton(
              onPressed: () {
                _controller.toPreviousPage();
              },
              child: const Text('上一页'),
            ),
            const Spacer(
              flex: 1,
            ),
            ElevatedButton(
              onPressed: () {
                _controller.toNextPage();
              },
              child: const Text('下一页'),
            ),
            const Spacer(
              flex: 1,
            ),
            ElevatedButton(
              onPressed: () {
                _controller.toLastPage();
              },
              child: const Text('尾页'),
            ),
          ],
        )
      ],
    );
  }
  List<Widget> _buildImages(BuildContext context) {
    List<Widget> res = [];
    for (String url in imageUrls) {
      res.add(
        Image.network(
          url,
          fit: BoxFit.cover, // 使图片宽度占满
          width: MediaQuery.of(context).size.width, // 设置宽度为屏幕宽度
          errorBuilder: (context, error, stackTrace) {
            // 在加载失败时返回一个占位图,确保图片占用固定高度
            return Container(
              height: MediaQuery.of(context).size.height,
              color: Colors.grey,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const Text(
                    'Image loading error:',
                    style: TextStyle(
                      color: Colors.red,
                    ),
                  ),
                  Text(
                    "原因: $error\n追溯:$stackTrace",
                    style: const TextStyle(
                      color: Colors.white,
                    ),
                    maxLines: 9,
                    overflow: TextOverflow.ellipsis,
                  ),
                ],
              ),
            );
          },
        ),
      );
    }
    return res;
  }
  Map<String, Widget> _indicatorBuilder(int index) {
    return {
      'plain': Container(
        padding: const EdgeInsets.all(10),
        child: Column(
          children: [
            const Text(
              'plain',
              style: TextStyle(
                color: Colors.grey,
              ),
            ),
            Container(
              width: 30,
              height: 10,
              decoration: const BoxDecoration(color: Colors.white),
            ),
          ],
        ),
      ),
      'active': Container(
        padding: const EdgeInsets.all(10),
        child: Column(
          children: [
            const Icon(
              Icons.arrow_circle_down,
              color: Colors.amber,
            ),
            const Text(
              'active',
              style: TextStyle(
                color: Colors.red,
                fontSize: 20,
                fontWeight: FontWeight.w700,
              ),
            ),
            Container(
              width: 30,
              height: 10,
              decoration: BoxDecoration(
                color: switch (index) {
                  0 => Colors.blue,
                  1 => Colors.red,
                  2 => Colors.green,
                  3 => Colors.pink,
                  _ => Colors.purple,
                },
              ),
            ),
          ],
        ),
      )
    };
  }
}

其效果如下:

可以看到,由于可以完全自定义轮播指示器和轮播项,只要你拥有足够丰富的想象力,可以包装出一些复杂但精致的轮播。

4. API 文档

CarouselController 类

CarouselController 类是一个用于管理轮播图控制的类。它包含了多个方法,用于控制轮播图的跳转、动画效果和状态通知。

构造函数

CarouselController(
  int total, {
  int initialPage = 0,
  bool keepPage = true,
  double viewportFraction = 1.0,
  Curve curve = Curves.ease,
  Duration duration = const Duration(milliseconds: 300),
})

参数

  • total (int): 表示轮播的总页面数量。
  • initialPage (int): 表示初始页面索引,默认为0。
  • keepPage (bool): 表示是否保持页面,即在翻页后是否保存页面状态,默认为 true
  • viewportFraction (double): 表示可视视口占整个页面宽度的比例,默认为 1.0。
  • curve (Curve): 页面切换动画曲线,默认为 Curves.ease
  • duration (Duration): 页面切换动画播放时间,默认为 Duration(milliseconds: 300)

方法

goToPage(int page)

此方法用于通过自定义方法滚动轮播到指定的页面。

  • page (int): 要跳转到的页面的索引。

toFirstPage()

此方法用于通过自定义方法将轮播滚动到第一个页面。

toPreviousPage()

此方法用于通过自定义方法将轮播滚动到上一页。如果当前已经是第一页,则会跳转到最后一页。

toNextPage()

此方法用于通过自定义方法将轮播滚动到下一页。如果当前已经是最后一页,则会跳转到第一页。

toLastPage()

此方法用于通过自定义方法将轮播滚动到最后一页。

属性

currentPage

  • 类型: int
  • 描述: 获取或设置当前轮播的页面索引。通过获取 currentPage 属性,可以获得当前页面的索引,通过设置 currentPage 属性,可以跳转到指定的页面。

示例

final controller = CarouselController(3);
// 获取当前页面索引
int current = controller.currentPage;
// 将轮播滚动到第二页
controller.goToPage(1);
// 将轮播滚动到下一页
controller.toNextPage();

Carousel 类

Carousel 类是一个通用的轮播组件,它允许您在Flutter应用程序中创建各种类型的轮播图。您可以配置轮播图的外观、轮播控制和回调函数。

构造函数

Carousel(
  List<Widget> units, {
  Key? key,
  double height = 400.0,
  double width = 0.0,
  FunctionWithAInt? onUnitTapped,
  FunctionWithAInt? onIndicatorTapped,
  bool useindicator = true,
  Color indicatorColor = Colors.white,
  Color currentIndicatorColor = Colors.blue,
  double indicatorWidth = 40.0,
  double indicatorHeight = 26.0,
  double indicatorMargin = 3.0,
  double indicatorToBottom = 10.0,
  BoxShape indicatorShape = BoxShape.rectangle,
  FunctionIndicatorBuilder? indicatorBuilder,
  bool pageSnapping = true,
  bool padEnds = true,
  Clip clipBehavior = Clip.hardEdge,
  bool reverse = false,
  Axis scrollDirection = Axis.horizontal,
  CarouselController? controller,
})

参数

  • units (List<Widget>): 要轮播的组件列表。
  • key (Key?): 可选参数,用于在小部件树中标识小部件。
  • height (double): 轮播组件的高度,默认为 400.0。
  • width (double): 轮播组件的宽度,默认为 0.0(自动适应屏幕宽度)。
  • onUnitTapped (FunctionWithAInt?): 当轮播单元被点击时触发的回调函数,可选,接收一个整数参数,表示被点击的单元索引。
  • onIndicatorTapped (FunctionWithAInt?): 当指示器被点击时触发的回调函数,可选,接收一个整数参数,表示被点击的指示器索引。
  • useindicator (bool): 控制是否显示轮播图下方的指示器,默认为 true
  • indicatorColor (Color): 指示器的默认颜色,默认为白色。
  • currentIndicatorColor (Color): 当前选中指示器的颜色,默认为蓝色。
  • indicatorWidth (double): 每个指示器的宽度,默认为 40.0。
  • indicatorHeight (double): 每个指示器的高度,默认为 26.0。
  • indicatorMargin (double): 指示器之间的水平间距,默认为 3.0。
  • indicatorToBottom (double): 指示器距离底部的距离,默认为 10.0。
  • indicatorShape (BoxShape): 指示器的形状,可以是 BoxShape.rectangleBoxShape.circle,默认为 BoxShape.rectangle
  • indicatorBuilder (FunctionIndicatorBuilder?): 自定义指示器构建函数,可选,用于创建指示器的自定义外观。
  • pageSnapping (bool): 是否启用页面快速吸附,默认为 true
  • padEnds (bool): 是否在轮播首尾添加额外的页面,默认为 true
  • clipBehavior (Clip): 指示如何剪切轮播单元的内容,默认为 Clip.hardEdge
  • reverse (bool): 是否以反向顺序滚动轮播单元,默认为 false
  • scrollDirection (Axis): 轮播单元滚动方向,可以是 Axis.horizontalAxis.vertical,默认为 Axis.horizontal
  • controller (CarouselController?): 轮播控制器,可选,用于控制轮播的行为和状态。
  • disableIndicatorDefaultCallbacks (bool): 是否禁用默认指示器回调函数,默认为 false。当为 true 时,不执行默认的指示器点击事件。

示例

Carousel(
  [
    Image.network('https://example.com/image1.jpg'),
    Image.network('https://example.com/image2.jpg'),
    Image.network('https://example.com/image3.jpg'),
  ],
  height: 300.0,
  onUnitTapped: (int index) {
    print('点击了第 $index 个轮播单元');
  },
  indicatorColor: Colors.red,
  currentIndicatorColor: Colors.green,
),
目录
相关文章
|
1月前
|
iOS开发 UED
Flutter 动态修改应用图标功能指南
探索Flutter中动态应用图标的实现方法,了解如何为用户提供独特体验,促进用户升级和应用内购买。
119 0
Flutter 动态修改应用图标功能指南
|
1月前
|
移动开发 JavaScript 前端开发
【Uniapp 专栏】Uniapp 与 Flutter 的功能特点对比
【5月更文挑战第15天】Uniapp 和 Flutter 是跨平台开发的热门框架。Uniapp 以其强大的跨平台兼容性和基于 Vue.js 的易学性著称,适合快速开发适用于 iOS、Android 和 H5 的应用。其丰富的组件生态简化了功能集成。然而,在复杂场景下,性能可能不及原生。Flutter 则以其全新渲染引擎实现流畅界面和高度自定义,性能接近原生,但学习成本较高,需处理特定平台适配。适用于高要求的项目。两者各有优势,选择应考虑项目需求、技术储备和开发周期。
【Uniapp 专栏】Uniapp 与 Flutter 的功能特点对比
|
14天前
|
Dart 监控 开发者
详细介绍Flutter Profiler的功能、使用方法以及如何利用它来提升应用的性能
【6月更文挑战第11天】Flutter Profiler是用于优化Flutter应用的关键工具,提供CPU、GPU、内存和网络分析。它帮助开发者监控运行时性能,识别瓶颈,如CPU过度使用、渲染问题、内存泄漏和网络效率低。通过选择分析类型、开始分析、查看结果,开发者可进行针对性优化。最佳实践包括定期分析、结合实际场景、关注关键指标及结合其他工具。有效利用Profiler能提升应用性能和用户体验。
39 2
|
14天前
|
开发框架 开发者 UED
Flutter作为一款跨平台的移动应用开发框架,自然也提供了丰富的工具和功能来支持可访问性和无障碍设计
【6月更文挑战第11天】Flutter是一款注重可访问性设计的跨平台移动应用开发框架,提供语义化组件、文本缩放、对比度调整、动态内容更新通知和键盘导航等功能,支持无障碍体验。开发者应结合简化操作、清晰反馈、多输入方式支持及测试优化等原则,以创建包容性更强的应用,满足不同用户需求,体现社会责任。
23 1
|
14天前
|
开发框架 Dart JavaScript
深入探讨Flutter中的Web支持功能,以及如何利用Flutter构建跨平台Web应用的最佳实践
【6月更文挑战第11天】Flutter,Google的开源跨平台框架,已延伸至Web支持,让开发者能用同一代码库构建移动和Web应用。Flutter Web基于Dart转JavaScript,利用WebAssembly和JavaScript在Web上运行。构建Web应用最佳实践包括选择合适项目、优化性能、进行兼容性测试和利用Flutter的声明式UI、热重载等优势。尽管性能挑战存在,Flutter Web为跨平台开发提供了更多机会和潜力。
39 1
|
1月前
|
设计模式 JavaScript 前端开发
flutter组件封装技巧
工厂函数不会自动调用,需要手动调用
27 3
|
1月前
|
Dart
Flutter 中优雅切换应用主题的组件
【Flutter】使用adaptive_theme组件优雅切换应用主题:封装MaterialApp,支持light/dark/system模式,自定义色彩,保存选择,含调试按钮。安装配置、设置主题、监听切换、自定义颜色、读取配置步骤详细。代码示例与学习路径推荐。[查看完整教程](https://flutter.ducafecat.com/blog/flutter-app-theme-switch)
Flutter 中优雅切换应用主题的组件
|
1月前
|
前端开发 搜索推荐 UED
【Flutter前端技术开发专栏】Flutter中的高级UI组件应用
【4月更文挑战第30天】探索Flutter的高级UI组件,如`TabBar`、`Drawer`、`BottomSheet`,提升应用体验和美观度。使用高级组件能节省开发时间,提供内置交互逻辑和优秀视觉效果。示例代码展示了如何实现底部导航栏、侧边导航和底部弹出菜单。同时,自定义组件允许个性化设计和功能扩展,但也带来性能优化和维护挑战。参考Flutter官方文档和教程,深入学习并有效利用这些组件。
【Flutter前端技术开发专栏】Flutter中的高级UI组件应用
|
1月前
|
Web App开发 Ubuntu 应用服务中间件
Flutter笔记:Web支持原理与实践
Flutter笔记:Web支持原理与实践
134 0
|
1月前
|
Linux Android开发 iOS开发
Flutter笔记:滑块及其实现分析1
Flutter笔记:滑块及其实现分析1
164 0