阅读视图

发现新文章,点击刷新页面。

【React Native】自定义轮播图组件 Banner

一、组件简介

Banner 是基于 react-native-pager-view 实现的高性能轮播组件,支持无限循环滚动自动播放垂直/水平方向切换自定义分页指示器等功能,适用于广告轮播、内容展示、产品推荐等场景。组件通过封装底层滚动逻辑,提供简洁的 API 接口,降低开发成本。


二、核心功能

功能 描述
无限循环滚动 支持首尾无缝衔接,循环展示数据(需开启 loop 属性)
自动播放 自动切换轮播项(可配置延迟时间 autoplayDelay 和间隔 autoplayInterval
垂直/水平滚动 支持垂直(vertical={true})或水平(默认)滚动方向
自定义分页指示器 支持自定义分页点样式(颜色、大小、间距)、容器样式(背景、边距等)
手动/自动滚动控制 可禁用自动播放(autoplay={false}),或通过 scrollEnabled 控制手动滚动
滚动事件回调 提供 onScrollIndex(切换回调)和 onScroll(滚动过程回调)

三、属性详解(Props)

1. 基础样式与容器

属性名 类型 默认值 描述
style StyleProp<ViewStyle> undefined 自定义 Banner 容器样式(如背景色、边距、圆角等)
vertical boolean false 是否垂直滚动(默认水平滚动)
scrollEnabled boolean true 是否允许手动滚动(禁用后仅自动播放)

2. 数据与渲染

属性名 类型 默认值 描述
data any[] | undefined undefined 轮播数据源(必须为数组,长度需 ≥1)
renderItem (item: any, index: number) => React.ReactElement undefined 渲染单个轮播项的函数(必传)
keyExtractor (item: any, index: number) => string undefined 生成唯一 key 的方法(建议提供,避免渲染警告)

3. 循环与自动播放

属性名 类型 默认值 描述
loop boolean true 是否开启无限循环(需 data.length ≥ 2,否则无效)
autoplay boolean true 是否自动播放(默认开启)
autoplayDelay number 1000 自动播放前的延迟时间(毫秒,仅在首次加载时生效)
autoplayInterval number 5000 自动切换间隔时间(毫秒)

4. 分页指示器

属性名 类型 默认值 描述
showsPagination boolean false 是否显示分页指示器(默认隐藏)
paginationStyle StyleProp<ViewStyle> undefined 分页指示器容器样式(如背景色、内边距、位置等)
dotStyle StyleProp<ViewStyle> undefined 普通分页点样式(如大小、颜色、间距等,与 dotColor 合并生效)
activeDotStyle StyleProp<ViewStyle> undefined 当前分页点样式(如大小、颜色、边框等,与 activeDotColor 合并生效)
dotColor string #CCCCCC 普通分页点颜色(默认浅灰色)
activeDotColor string #FFFFFF 当前分页点颜色(默认白色)

5. 回调函数

属性名 类型 默认值 描述
onScrollIndex (index: number) => void undefined 切换到指定轮播项时的回调(参数为真实数据索引)
onScroll (e: { offset: number; position: number }) => void undefined 滚动过程中的回调(offset 为偏移量,position 为当前页位置)

四、使用示例

1. 基础用法(水平轮播)

import React from 'react';
import { View, StyleSheet } from 'react-native';
import Banner from './Banner'; // 引入组件

const App = () => {
  const data = [
    { id: 1, image: 'https://example.com/banner1.jpg' },
    { id: 2, image: 'https://example.com/banner2.jpg' },
    { id: 3, image: 'https://example.com/banner3.jpg' },
  ];

  const renderItem = ({ item }) => (
    <View style={styles.bannerItem}>
      <Image source={{ uri: item.image }} style={styles.image} />
    </View>
  );

  return (
    <View style={styles.container}>
      <Banner
        data={data}
        renderItem={renderItem}
        loop={true}
        autoplay={true}
        autoplayInterval={3000}
        showsPagination={true}
        dotColor="#999"
        activeDotColor="#FF5500"
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  bannerItem: {
    width: '100%',
    height: 200,
  },
  image: {
    width: '100%',
    height: '100%',
    resizeMode: 'cover',
  },
});

export default App;

2. 自定义分页指示器(垂直滚动)

<Banner
  data={data}
  renderItem={renderItem}
  vertical={true} // 垂直滚动
  loop={true}
  autoplay={true}
  showsPagination={true}
  paginationStyle={{
    backgroundColor: 'rgba(0,0,0,0.3)', // 分页容器背景
    paddingHorizontal: 16, // 分页点左右边距
  }}
  dotStyle={{
    width: 6, // 普通分页点宽度
    height: 6,
    marginHorizontal: 4, // 分页点间距
  }}
  activeDotStyle={{
    borderWidth: 2, // 当前分页点边框
    borderColor: '#FFF',
  }}
  onScrollIndex={(index) => console.log('当前索引:', index)} // 切换回调
/>

❌