在这里插入图片描述

前言

轮播图是展示精选内容的有效方式,在青花瓷App中,我们将用轮播图展示珍贵的青花瓷藏品图片。每一张图片都是一件艺术品的特写,配合优雅的切换动画,为用户带来沉浸式的视觉体验。

轮播图的设计灵感来源于博物馆的展柜,每一帧都如同一个独立的展示空间,让藏品成为绝对的视觉焦点。切换动画模拟了展柜灯光渐变的效果,平滑而不突兀。

轮播图数据模型

首先定义轮播图项的数据结构,包含图片、标题和跳转链接等信息。

// lib/models/banner_item.dart
class BannerItem {
  final String id;
  final String imageUrl;
  final String title;
  final String subtitle;
  final String targetRoute;

  const BannerItem({
    required this.id,
    required this.imageUrl,
    required this.title,
    required this.subtitle,
    required this.targetRoute,
  });
}


数据模型包含了轮播图所需的全部信息:`id`用于唯一标识,`imageUrl`是图片地址,`title`和`subtitle`提供文字说明,`targetRoute`定义点击后的跳转目标。使用`required`关键字确保创建对象时必须提供所有必要参数。

## 轮播图状态管理

轮播图需要管理当前页面索引和自动播放定时器,使用StatefulWidget实现。

```dart
// lib/widgets/banner/banner_carousel.dart
import 'dart:async';
import 'package:flutter/material.dart';

class BannerCarousel extends StatefulWidget {
  final List<BannerItem> items;
  
  const BannerCarousel({super.key, required this.items});

  
  State<BannerCarousel> createState() => _BannerCarouselState();
}

class _BannerCarouselState extends State<BannerCarousel> {
  late PageController _pageController;
  int _currentPage = 0;
  Timer? _autoPlayTimer;
}

PageController用于控制页面切换,_currentPage记录当前显示的页面索引,_autoPlayTimer是自动播放的定时器。使用late关键字延迟初始化PageController,在initState中完成实际的初始化工作。

自动播放功能

实现轮播图的自动播放功能,每隔固定时间自动切换到下一张图片。

// lib/widgets/banner/banner_carousel.dart (续)

void initState() {
  super.initState();
  _pageController = PageController();
  _startAutoPlay();
}

void _startAutoPlay() {
  _autoPlayTimer = Timer.periodic(
    const Duration(seconds: 4),
    (timer) {
      if (_currentPage < widget.items.length - 1) {
        _currentPage++;
      } else {
        _currentPage = 0;
      }
      _pageController.animateToPage(
        _currentPage,
        duration: const Duration(milliseconds: 500),
        curve: Curves.easeInOut,
      );
    },
  );
}

Timer.periodic创建周期性定时器,每4秒触发一次。当到达最后一张图片时,自动回到第一张,形成循环播放。animateToPage方法实现平滑的页面切换动画,500毫秒的动画时长让切换效果既明显又不拖沓。

OpenHarmony轮播组件

在OpenHarmony端使用Swiper组件实现轮播图功能。

// ohos/entry/src/main/ets/components/BannerSwiper.ets
@Component
export struct BannerSwiper {
  @State currentIndex: number = 0;
  private bannerList: string[] = [
    'banner1.jpg',
    'banner2.jpg', 
    'banner3.jpg'
  ];

  build() {
    Swiper() {
      ForEach(this.bannerList, (item: string) => {
        Image($r(`app.media.${item}`))
          .width('100%')
          .height(200)
          .objectFit(ImageFit.Cover)
      })
    }
    .autoPlay(true)
    .interval(4000)
    .indicator(true)
    .onChange((index: number) => {
      this.currentIndex = index;
    })
  }
}

ArkTS的Swiper组件内置了轮播图的核心功能。autoPlay(true)开启自动播放,interval(4000)设置4秒的切换间隔,与Flutter端保持一致。indicator(true)显示页面指示器,onChange回调在页面切换时更新当前索引。这种声明式的API使得实现轮播图变得非常简洁。

轮播图UI构建

构建轮播图的完整UI,包括图片展示和页面指示器。

// lib/widgets/banner/banner_carousel.dart (续)

Widget build(BuildContext context) {
  return SizedBox(
    height: 200,
    child: Stack(
      children: [
        PageView.builder(
          controller: _pageController,
          itemCount: widget.items.length,
          onPageChanged: (index) {
            setState(() {
              _currentPage = index;
            });
          },
          itemBuilder: (context, index) {
            return BannerImage(item: widget.items[index]);
          },
        ),
        Positioned(
          bottom: 16,
          left: 0,
          right: 0,
          child: PageIndicator(
            count: widget.items.length,
            currentIndex: _currentPage,
          ),
        ),
      ],
    ),
  );
}

Stack组件将图片和指示器叠加显示,PageView.builder实现可滑动的页面视图。onPageChanged回调在用户手动滑动时更新当前页面索引,确保指示器状态同步。Positioned组件将指示器定位在底部中央位置。

页面指示器组件

自定义页面指示器,使用青花瓷风格的圆点设计。

// lib/widgets/banner/page_indicator.dart
class PageIndicator extends StatelessWidget {
  final int count;
  final int currentIndex;

  const PageIndicator({
    super.key,
    required this.count,
    required this.currentIndex,
  });

  
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: List.generate(count, (index) {
        return Container(
          margin: const EdgeInsets.symmetric(horizontal: 4),
          width: index == currentIndex ? 24 : 8,
          height: 8,
          decoration: BoxDecoration(
            color: index == currentIndex
                ? PorcelainColors.primaryBlue
                : Colors.white.withOpacity(0.5),
            borderRadius: BorderRadius.circular(4),
          ),
        );
      }),
    );
  }
}

指示器使用圆角矩形设计,当前页面的指示点宽度更大,形成视觉区分。选中状态使用青花蓝色,未选中状态使用半透明白色,在各种背景图片上都能保持良好的可见性。List.generate根据页面数量动态生成指示点。

资源释放

在组件销毁时释放定时器和控制器资源,防止内存泄漏。

// lib/widgets/banner/banner_carousel.dart (续)

void dispose() {
  _autoPlayTimer?.cancel();
  _pageController.dispose();
  super.dispose();
}

dispose方法是Flutter生命周期中释放资源的标准位置。首先取消定时器,然后释放页面控制器。使用?.空安全操作符确保即使定时器为null也不会报错。良好的资源管理习惯是编写高质量Flutter应用的关键。

总结

本篇文章完整介绍了青花瓷App轮播图组件的开发,包括数据模型、自动播放、页面指示器等功能。Flutter和OpenHarmony双端的实现展示了跨平台开发的一致性。下一篇文章将介绍藏品列表页面的实现。欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐