欢迎加入开源鸿蒙跨平台社区https://openharmonycrossplatform.csdn.net

在这里插入图片描述

📋 前言

轮播图(Swiper)是展示Banner、引导页、图片画廊等内容的核心组件。无论是电商应用的商品展示、新闻资讯的头条推荐,还是应用的新手引导,都离不开轮播组件的支持。react-native-swiper 是 React Native 生态中最流行的轮播组件,提供了流畅的滑动体验和丰富的定制功能。

🎯 库简介

基本信息

  • 库名称: @react-native-ohos/react-native-swiper
  • 版本信息:
    • 1.6.1 + @react-native-oh-tpl/react-native-swiper: 支持 RN 0.72 版本(已废弃)
    • 1.6.1 + @react-native-ohos/react-native-swiper: 支持 RN 0.72/0.77 版本
  • 官方仓库: https://github.com/leecade/react-native-swiper
  • 鸿蒙仓库: https://github.com/react-native-oh-library/react-native-swiper
  • 主要功能:
    • 🎠 流畅的轮播滑动体验
    • ⏪ 支持前后导航按钮
    • 📍 分页指示器
    • 🔄 自动播放
    • 👆 支持手势操作
    • 📱 全屏/非全屏模式

为什么需要 react-native-swiper?

特性 React Native ScrollView react-native-swiper
自动播放 ❌ 不支持 ✅ 支持
循环轮播 ❌ 不支持 ✅ 支持
分页指示器 ❌ 不支持 ✅ 支持
导航按钮 ❌ 不支持 ✅ 支持
懒加载 ❌ 不支持 ✅ 支持
HarmonyOS 支持 ⚠️ 部分支持 ✅ 完全支持

支持的功能

功能 说明 HarmonyOS 支持
horizontal 水平滚动
vertical 垂直滚动 ❌ 暂不支持
loop 循环模式
index 初始索引
autoplay 自动播放
autoplayTimeout 自动播放间隔
autoplayDirection 自动播放方向
showsButtons 显示导航按钮
showsPagination 显示分页指示器
paginationStyle 分页器样式
renderPagination 自定义分页器
dotStyle/activeDotStyle 圆点样式
dotColor/activeDotColor 圆点颜色
loadMinimal 懒加载模式
onIndexChanged 索引变化回调
scrollBy 手动滚动方法

💡 提示:RNOH 0.72.13 版本存在轮播图不居中问题,在 RNOH 0.72.19+ 版本已修复。

兼容性验证

在以下环境验证通过:

  • RNOH: 0.72.90; SDK: OpenHarmony 6.0.0 (API Version 20); IDE: DevEco Studio 6.0.2; ROM: 6.0.0

📦 安装步骤

1. 安装依赖

在项目根目录执行以下命令:

# npm
npm install @react-native-ohos/react-native-swiper --save

# yarn
yarn add @react-native-ohos/react-native-swiper

2. 验证安装

安装完成后,检查 package.json 文件,应该能看到新增的依赖:

{
  "dependencies": {
    "@react-native-ohos/react-native-swiper": "1.6.1",
    // ... 其他依赖
  }
}

🔧 HarmonyOS 平台配置

react-native-swiper 是纯 JavaScript 库,不需要原生模块配置,安装后即可直接使用。


📖 API 详解

🔷 基础属性

1. horizontal - 滚动方向 ⭐

如果为 true,子元素水平排列;否则垂直排列。

import Swiper from '@react-native-ohos/react-native-swiper';

const HorizontalSwiper = () => {
  return (
    <Swiper style={styles.wrapper} horizontal={true}>
      <View style={styles.slide}><Text>1</Text></View>
      <View style={styles.slide}><Text>2</Text></View>
      <View style={styles.slide}><Text>3</Text></View>
    </Swiper>
  );
};
2. loop - 循环模式 ⭐

设置为 false 可禁用连续循环模式。

⚠️ 重要提示:当同时使用 autoplay 自动播放和手动滑动时,建议设置 loop={false} 禁用循环模式。因为 loop={true} 会在首尾各添加一个虚拟 slide 来实现无限循环,这会导致自动播放和手动滑动时索引不同步,出现页面回退或闪烁的问题。

// 默认开启循环(可能导致自动播放和手动滑动冲突)
<Swiper loop={true}>
  <View style={styles.slide}><Text>循环轮播</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>

// 关闭循环(推荐用于自动播放场景)
<Swiper loop={false} autoplay={true}>
  <View style={styles.slide}><Text>非循环轮播</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>
3. index - 初始索引 ⭐

设置初始显示的轮播页面索引。

<Swiper index={2}>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
  <View style={styles.slide}><Text>3</Text></View>
</Swiper>
4. autoplay - 自动播放 ⭐

设置为 true 启用自动播放模式。

<Swiper autoplay={true}>
  <View style={styles.slide}><Text>自动播放</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
  <View style={styles.slide}><Text>3</Text></View>
</Swiper>
5. autoplayTimeout - 自动播放间隔

自动播放切换的时间间隔(秒)。

<Swiper autoplay={true} autoplayTimeout={3}>
  <View style={styles.slide}><Text>3秒间隔</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>
6. autoplayDirection - 播放方向

控制循环方向。

// 正向播放(默认)
<Swiper autoplay={true} autoplayDirection={true}>
  <View style={styles.slide}><Text>1 -> 2 -> 3 -> 1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>

// 反向播放
<Swiper autoplay={true} autoplayDirection={false}>
  <View style={styles.slide}><Text>3 -> 2 -> 1 -> 3</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>

🔷 分页指示器属性

7. showsPagination - 显示分页 ⭐

设置为 true 显示分页指示器。

<Swiper showsPagination={true}>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
  <View style={styles.slide}><Text>3</Text></View>
</Swiper>
8. paginationStyle - 分页器样式

自定义分页器的样式。

<Swiper
  showsPagination={true}
  paginationStyle={styles.pagination}
>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>

const styles = StyleSheet.create({
  pagination: {
    position: 'absolute',
    bottom: 20,
    left: 0,
    right: 0,
  },
});
9. renderPagination - 自定义分页器 ⭐

完全控制分页器的渲染方式。

<Swiper
  showsPagination={true}
  renderPagination={(index, total, context) => {
    return (
      <View style={styles.customPagination}>
        <Text style={styles.paginationText}>
          {index + 1} / {total}
        </Text>
      </View>
    );
  }}
>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
  <View style={styles.slide}><Text>3</Text></View>
</Swiper>

const styles = StyleSheet.create({
  customPagination: {
    position: 'absolute',
    bottom: 30,
    left: 0,
    right: 0,
    alignItems: 'center',
  },
  paginationText: {
    color: '#333',
    fontSize: 16,
    fontWeight: 'bold',
  },
});
10. dotStyle - 圆点样式

未激活圆点的样式。

<Swiper
  showsPagination={true}
  dotStyle={{ backgroundColor: 'rgba(0,0,0,0.2)', width: 8, height: 8 }}
  activeDotStyle={{ backgroundColor: '#007aff', width: 8, height: 8 }}
>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>
11. activeDotStyle - 激活圆点样式

当前激活圆点的样式。

<Swiper
  showsPagination={true}
  dotStyle={{ width: 6, height: 6, borderRadius: 3 }}
  activeDotStyle={{ width: 6, height: 6, borderRadius: 3, backgroundColor: '#00ff00' }}
>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>
12. dotColor / activeDotColor - 圆点颜色

简化的圆点颜色设置。

<Swiper
  showsPagination={true}
  dotColor="rgba(255,255,255,0.3)"
  activeDotColor="#ffffff"
>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>

🔷 导航按钮属性

13. showsButtons - 显示按钮 ⭐

设置为 true 显示左右导航按钮。

<Swiper showsButtons={true}>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
  <View style={styles.slide}><Text>3</Text></View>
</Swiper>
14. buttonWrapperStyle - 按钮容器样式

导航按钮容器的自定义样式。

<Swiper
  showsButtons={true}
  buttonWrapperStyle={{
    backgroundColor: 'transparent',
    flexDirection: 'row',
    position: 'absolute',
    top: 0,
    left: 0,
    flex: 1,
    paddingHorizontal: 10,
    paddingVertical: 10,
    justifyContent: 'space-between',
    alignItems: 'center',
  }}
>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>
15. nextButton / prevButton - 自定义按钮 ⭐

自定义前进和后退按钮。

<Swiper
  showsButtons={true}
  nextButton={<Text style={styles.buttonText}></Text>}
  prevButton={<Text style={styles.buttonText}></Text>}
>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>

const styles = StyleSheet.create({
  buttonText: {
    fontSize: 40,
    color: '#007aff',
    fontWeight: 'bold',
  },
});

🔷 尺寸属性

16. width / height - 尺寸设置 ⭐

如果不指定,默认使用全屏模式(flex: 1)。

// 自定义尺寸
<Swiper width={300} height={200}>
  <View style={[styles.slide, { width: 300, height: 200 }]}>
    <Text>固定尺寸轮播</Text>
  </View>
  <View style={[styles.slide, { width: 300, height: 200 }]}>
    <Text>2</Text>
  </View>
</Swiper>

🔷 懒加载属性

17. loadMinimal - 懒加载 ⭐

仅加载当前索引附近的页面。

<Swiper
  loadMinimal={true}
  loadMinimalSize={1}
>
  <View style={styles.slide}><Text>懒加载模式</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
  <View style={styles.slide}><Text>3</Text></View>
</Swiper>
18. loadMinimalSize - 懒加载数量

前后加载的页面数量。

<Swiper
  loadMinimal={true}
  loadMinimalSize={2}
>
  <View style={styles.slide}><Text>加载前后2</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
  <View style={styles.slide}><Text>3</Text></View>
  <View style={styles.slide}><Text>4</Text></View>
</Swiper>
19. loadMinimalLoader - 加载指示器

懒加载时的自定义加载指示器。

<Swiper
  loadMinimal={true}
  loadMinimalLoader={<ActivityIndicator size="large" color="#007aff" />}
>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>

🔷 滚动属性

20. scrollEnabled - 启用滚动 ⭐

启用/禁用滑动操作。

<Swiper scrollEnabled={true}>
  <View style={styles.slide}><Text>可滑动</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>

// 禁用滚动
<Swiper scrollEnabled={false}>
  <View style={styles.slide}><Text>禁止滑动</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>
21. pagingEnabled - 分页模式

滚动时是否按页面停止。

<Swiper pagingEnabled={true}>
  <View style={styles.slide}><Text>整页滚动</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>
22. showsHorizontalScrollIndicator - 显示滚动条

是否显示水平滚动指示器。

<Swiper showsHorizontalScrollIndicator={false}>
  <View style={styles.slide}><Text>隐藏滚动条</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>
23. bounces - 弹性效果

滚动到边缘时的弹性效果。

<Swiper bounces={true}>
  <View style={styles.slide}><Text>弹性效果</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>

🔷 回调属性

24. onIndexChanged - 索引变化回调 ⭐

用户滑动后触发。

const [currentIndex, setCurrentIndex] = useState(0);

<Swiper
  onIndexChanged={(index) => {
    console.log('当前索引:', index);
    setCurrentIndex(index);
  }}
>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
  <View style={styles.slide}><Text>3</Text></View>
</Swiper>
25. onScrollBeginDrag - 开始拖动回调

开始拖动时触发。

<Swiper
  onScrollBeginDrag={(e, state, context) => {
    console.log('开始拖动', state.index);
  }}
>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>
26. onMomentumScrollEnd - 滚动结束回调

滚动动画结束时触发。

<Swiper
  onMomentumScrollEnd={(e, state, context) => {
    console.log('滚动结束', state.index);
  }}
>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>
27. onTouchStart / onTouchEnd - 触摸回调

触摸开始和结束时触发。

<Swiper
  onTouchStart={() => console.log('触摸开始')}
  onTouchEnd={() => console.log('触摸结束')}
>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>

📱 完整示例

本节展示一个综合性的轮播图应用示例,包含了 Banner 轮播、带导航按钮的引导页和图片画廊三种常见场景。

⚠️ 类型声明问题@react-native-ohos/react-native-swiper 包中没有 react-native-swiper 的类型声明。

解决方案:在 src/types 目录下创建 react-native-swiper.d.ts 类型声明文件,内容如下:

declare module 'react-native-swiper' {
  import { Component } from 'react';
  import { ViewStyle, StyleProp, NativeSyntheticEvent, NativeScrollEvent, ScrollViewProps } from 'react-native';

  interface SwiperState {
    autoplayEnd: false;
    loopJump: false;
    width: number;
    height: number;
    offset: { x: number; y: number };
    total: number;
    index: number;
    dir: 'x' | 'y';
  }

  interface SwiperInternals extends SwiperState {
    isScrolling: boolean;
  }

  interface SwiperProps extends Omit<ScrollViewProps, 'onScrollBeginDrag' | 'onMomentumScrollEnd'> {
    horizontal?: boolean;
    loop?: boolean;
    index?: number;
    showsButtons?: boolean;
    autoplay?: boolean;
    onIndexChanged?: (index: number) => void;
    width?: number;
    height?: number;
    style?: StyleProp<ViewStyle>;
    containerStyle?: StyleProp<ViewStyle>;
    loadMinimal?: boolean;
    loadMinimalSize?: number;
    loadMinimalLoader?: React.ReactNode;
    showsPagination?: boolean;
    paginationStyle?: StyleProp<ViewStyle>;
    renderPagination?: (index: number, total: number, swiper: Swiper) => React.ReactNode;
    dot?: React.ReactNode;
    activeDot?: React.ReactNode;
    dotStyle?: StyleProp<ViewStyle>;
    dotColor?: string;
    activeDotColor?: string;
    activeDotStyle?: StyleProp<ViewStyle>;
    autoplayTimeout?: number;
    autoplayDirection?: boolean;
    buttonWrapperStyle?: StyleProp<ViewStyle>;
    nextButton?: React.ReactNode;
    prevButton?: React.ReactNode;
    onScrollBeginDrag?: (e: NativeSyntheticEvent<NativeScrollEvent>, state: SwiperInternals, swiper: Swiper) => void;
    onMomentumScrollEnd?: (e: NativeSyntheticEvent<NativeScrollEvent>, state: SwiperInternals, swiper: Swiper) => void;
    pagingEnabled?: boolean;
    showsHorizontalScrollIndicator?: boolean;
    showsVerticalScrollIndicator?: boolean;
    bounces?: boolean;
    scrollsToTop?: boolean;
    removeClippedSubviews?: boolean;
    automaticallyAdjustContentInsets?: boolean;
    scrollEnabled?: boolean;
  }

  class Swiper extends Component<SwiperProps, SwiperState> {
    scrollBy(index?: number, animated?: boolean): void;
    scrollTo(index: number, animated?: boolean): void;
  }

  export = Swiper;
}

然后即可使用 import Swiper from 'react-native-swiper' 进行导入。

import React from 'react';
import {
  View,
  Text,
  Image,
  StyleSheet,
  ScrollView,
} from 'react-native';
import Swiper from 'react-native-swiper';

const SwiperDemo = () => {
  const banners = [
    { id: 1, image: 'https://picsum.photos/400/200?random=1', title: '热门活动' },
    { id: 2, image: 'https://picsum.photos/400/200?random=2', title: '新品上市' },
    { id: 3, image: 'https://picsum.photos/400/200?random=3', title: '限时优惠' },
  ];

  const guidePages = [
    { id: 1, bgColor: '#FFE4E1', title: '引导页 1', subtitle: '了解产品特性' },
    { id: 2, bgColor: '#E1FFE4', title: '引导页 2', subtitle: '快速上手指南' },
    { id: 3, bgColor: '#E1E4FF', title: '引导页 3', subtitle: '开始使用吧' },
  ];

  const galleryImages = [
    { id: 1, uri: 'https://picsum.photos/300/400?random=10' },
    { id: 2, uri: 'https://picsum.photos/300/400?random=11' },
    { id: 3, uri: 'https://picsum.photos/300/400?random=12' },
    { id: 4, uri: 'https://picsum.photos/300/400?random=13' },
    { id: 5, uri: 'https://picsum.photos/300/400?random=14' },
  ];

  return (
    <ScrollView style={styles.container}>
      <Text style={styles.sectionTitle}>1. Banner 轮播图</Text>
      <View style={styles.bannerContainer}>
        <Swiper
          style={styles.bannerWrapper}
          loop={false}
          showsButtons={false}
          showsPagination={true}
          autoplay={true}
          autoplayTimeout={3}
          dotStyle={styles.dot}
          activeDotStyle={styles.activeDot}
        >
          {banners.map((banner) => (
            <View key={banner.id} style={styles.bannerSlide}>
              <Image source={{ uri: banner.image }} style={styles.bannerImage} />
              <View style={styles.titleContainer}>
                <Text style={styles.bannerTitle}>{banner.title}</Text>
              </View>
            </View>
          ))}
        </Swiper>
      </View>

      <Text style={styles.sectionTitle}>2. 带导航按钮的引导页</Text>
      <View style={styles.guideContainer}>
        <Swiper
          style={styles.guideWrapper}
          loop={false}
          showsButtons={true}
          showsPagination={true}
          prevButton={<Text style={styles.navButton}></Text>}
          nextButton={<Text style={styles.navButton}></Text>}
        >
          {guidePages.map((page) => (
            <View key={page.id} style={[styles.guideSlide, { backgroundColor: page.bgColor }]}>
              <Text style={styles.guideTitle}>{page.title}</Text>
              <Text style={styles.guideSubtitle}>{page.subtitle}</Text>
            </View>
          ))}
        </Swiper>
      </View>

      <Text style={styles.sectionTitle}>3. 图片画廊</Text>
      <View style={styles.galleryContainer}>
        <Swiper
          style={styles.galleryWrapper}
          loop={false}
          showsPagination={true}
          showsButtons={false}
          dotStyle={styles.galleryDot}
          activeDotStyle={styles.galleryActiveDot}
        >
          {galleryImages.map((image) => (
            <View key={image.id} style={styles.gallerySlide}>
              <Image source={{ uri: image.uri }} style={styles.galleryImage} />
            </View>
          ))}
        </Swiper>
      </View>
    </ScrollView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f5f5f5',
  },
  sectionTitle: {
    fontSize: 16,
    fontWeight: 'bold',
    color: '#333',
    marginHorizontal: 16,
    marginTop: 20,
    marginBottom: 10,
  },
  bannerContainer: {
    height: 200,
  },
  bannerWrapper: {
    height: 200,
  },
  bannerSlide: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  bannerImage: {
    width: '100%',
    height: '100%',
    resizeMode: 'cover',
  },
  titleContainer: {
    position: 'absolute',
    bottom: 0,
    left: 0,
    right: 0,
    backgroundColor: 'rgba(0,0,0,0.3)',
    padding: 8,
  },
  bannerTitle: {
    color: '#fff',
    fontSize: 16,
    fontWeight: 'bold',
  },
  dot: {
    backgroundColor: 'rgba(255,255,255,0.5)',
    width: 6,
    height: 6,
    borderRadius: 3,
  },
  activeDot: {
    backgroundColor: '#fff',
    width: 6,
    height: 6,
    borderRadius: 3,
  },
  guideContainer: {
    height: 250,
    marginHorizontal: 16,
    borderRadius: 12,
    overflow: 'hidden',
  },
  guideWrapper: {
    height: 250,
  },
  guideSlide: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  guideTitle: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 12,
  },
  guideSubtitle: {
    fontSize: 14,
    color: '#666',
  },
  navButton: {
    fontSize: 50,
    color: '#007aff',
    fontWeight: '200',
  },
  galleryContainer: {
    height: 300,
    marginHorizontal: 20,
    borderRadius: 12,
    overflow: 'hidden',
    marginBottom: 20,
  },
  galleryWrapper: {
    height: 300,
  },
  gallerySlide: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  galleryImage: {
    width: '100%',
    height: '100%',
    resizeMode: 'cover',
  },
  galleryDot: {
    backgroundColor: 'rgba(0,0,0,0.2)',
    width: 6,
    height: 6,
    borderRadius: 3,
  },
  galleryActiveDot: {
    backgroundColor: '#007aff',
    width: 6,
    height: 6,
    borderRadius: 3,
  },
});

export default SwiperDemo;

🔧 高级技巧

1. 使用 scrollBy 方法手动控制

const swiperRef = useRef(null);

<Swiper ref={swiperRef} style={styles.wrapper}>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
  <View style={styles.slide}><Text>3</Text></View>
</Swiper>

// 手动滚动到指定页面
<Button
  title="滚动到第2页"
  onPress={() => swiperRef.current.scrollBy(1, true)}
/>

// 滚动回第1页
<Button
  title="滚动回第1页"
  onPress={() => swiperRef.current.scrollBy(-1, true)}
/>

2. 自定义数字分页器

<Swiper
  showsPagination={true}
  renderPagination={(index, total, context) => {
    return (
      <View style={styles.numberPagination}>
        {Array.from({ length: total }).map((_, i) => (
          <TouchableOpacity
            key={i}
            onPress={() => context.scrollBy && context.scrollBy(i - index)}
          >
            <Text style={[
              styles.numberText,
              i === index && styles.activeNumberText
            ]}>
              {i + 1}
            </Text>
          </TouchableOpacity>
        ))}
      </View>
    );
  }}
>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
  <View style={styles.slide}><Text>3</Text></View>
</Swiper>

const styles = StyleSheet.create({
  numberPagination: {
    flexDirection: 'row',
    position: 'absolute',
    bottom: 20,
    left: 0,
    right: 0,
    justifyContent: 'center',
    gap: 10,
  },
  numberText: {
    fontSize: 14,
    color: '#999',
    padding: 8,
  },
  activeNumberText: {
    color: '#007aff',
    fontWeight: 'bold',
  },
});

3. 控制自动播放

const [isAutoPlay, setIsAutoPlay] = useState(true);

<Swiper autoplay={isAutoPlay}>
  <View style={styles.slide}><Text>1</Text></View>
  <View style={styles.slide}><Text>2</Text></View>
</Swiper>

<Button
  title={isAutoPlay ? '暂停' : '播放'}
  onPress={() => setIsAutoPlay(!isAutoPlay)}
/>

❓ 常见问题

1. 轮播图不居中

问题:RNOH 0.72.13 版本轮播图不居中。

解决方案

  • 升级到 RNOH 0.72.19+ 版本
  • 或者手动设置 widthheight 属性

2. 滑动到最后一页卡住

问题:关闭循环后,滑动到最后一页无法继续。

解决方案

  • 确认 loop={false} 是有意为之
  • 如需循环轮播,设置为 loop={true}

3. 内存占用过高

问题:多张图片时内存占用过大。

解决方案

  • 启用懒加载 loadMinimal={true}
  • 调整 loadMinimalSize 减少预加载数量
  • 使用适当的图片压缩

4. 嵌套 ScrollView 冲突

问题:在 ScrollView 中使用 Swiper 滑动冲突。

解决方案

  • 设置 scrollEnabled={false} 禁用 Swiper 滑动
  • 或在父级 ScrollView 设置 nestedScrollEnabled={false}

📚 参考资料


✅ 总结

通过本文,您已经学会了:

  • ✅ 安装和配置 react-native-swiper
  • ✅ 实现 Banner 轮播图
  • ✅ 配置分页指示器
  • ✅ 添加导航按钮
  • ✅ 实现自动播放
  • ✅ 使用懒加载优化性能
  • ✅ 手动控制滚动

希望本文能帮助你在 HarmonyOS 项目中顺利集成轮播图功能!

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐