当前位置: 首页 > news >正文

基于react native的自定义轮播图

基于react native的自定义轮播图

    • 效果示例图
    • 示例代码

效果示例图

在这里插入图片描述

示例代码

import React, {useEffect, useRef, useState} from 'react';
import {Animated,PanResponder,StyleSheet,Text,View,Dimensions,
} from 'react-native';
import {pxToPd} from '../../common/js/device';const TestSwiper = () => {//动态获取的值const [tempList, setTempList] = useState([{id: 1},{id: 2},{id: 3},{id: 4},]);const [swiperList, setSwiperList] = useState([]);const swiperListRef = useRef([]);//定时器手柄const intervalHandleRef = useRef(null);//手势滑动区域节点const animatedViewRef = useRef(null);//单个切换页面的宽度const deviceWidth = Dimensions.get('window').width;// 默认显示下标的页面let currentIndexRef = useRef(0);const panResponderEnabled = useRef(true);//滑动的距离const defaultMove = -currentIndexRef.current * deviceWidth;const pan = useRef(new Animated.Value(defaultMove)).current;//手势操作const panResponder = useRef(PanResponder.create({onStartShouldSetPanResponder: () => true,onPanResponderGrant: () => {clearInterval(intervalHandleRef.current); // 暂停自动轮播panResponderEnabled.current = true;},//处理手势移动事件,其中使用了`dx`参数来表示在x轴上的移动距离onPanResponderMove: (evt, gestureState) => {//获取当前滚动区域有几个孩子节点const count = animatedViewRef.current._children.length;//每次移动的距离const moveX = -currentIndexRef.current * deviceWidth;//当移动到最左侧或者最右侧时,禁止拖动const start = currentIndexRef.current == 0 && gestureState.dx > 0;const end = currentIndexRef.current == count - 1 && gestureState.dx < 0;if (start || end) {// 禁止继续拖动return false;}pan.setValue(moveX + gestureState.dx);if (panResponderEnabled.current) {panResponderEnabled.current = false; // 防止多次暂停自动轮播clearInterval(intervalHandleRef.current); // 暂停自动轮播}},//处理手势释放时的逻辑onPanResponderRelease: (_, gestureState) => {//获取当前滚动区域有几个孩子节点const count = animatedViewRef.current._children.length;//当手指拖动区域大于100的时候,开始切换页面if (Math.abs(gestureState.dx) > 100) {let newPageIndex = currentIndexRef.current;if (gestureState.dx > 0) {newPageIndex = Math.max(0, currentIndexRef.current - 1);} else {newPageIndex = Math.min(count - 1, currentIndexRef.current + 1);}const moveX = -newPageIndex * deviceWidth;currentIndexRef.current = newPageIndex;Animated.timing(pan, {toValue: moveX,duration: 300,useNativeDriver: true,}).start(() => {if (newPageIndex == count - 1) {currentIndexRef.current = 0;pan.setValue(0);}autoPlayAPI(); // 继续自动轮播});} else {pan.setValue(-currentIndexRef.current * deviceWidth);}if (!panResponderEnabled.current) {autoPlayAPI(); // 继续自动轮播}},}),).current;//自动轮播const autoPlayAPI = () => {const max = swiperListRef.current.length - 1;if (intervalHandleRef.current) {clearInterval(intervalHandleRef.current);}intervalHandleRef.current = setInterval(() => {let newPageIndex = 0;if (currentIndexRef.current == max) {newPageIndex = 0;} else {newPageIndex = currentIndexRef.current + 1;}const moveX = -newPageIndex * deviceWidth;currentIndexRef.current = newPageIndex;Animated.timing(pan, {toValue: moveX,duration: 300,useNativeDriver: true,}).start(() => {if (newPageIndex == max) {currentIndexRef.current = 0;pan.setValue(0);autoPlayAPI();}});}, 3000);};//初始化const initFunction = () => {let tempArr = [...tempList];let firstArr = tempArr[0];let contactArr = tempArr.concat(firstArr);swiperListRef.current = contactArr;setSwiperList(() => contactArr);autoPlayAPI();};useEffect(() => {initFunction();return () => {clearInterval(intervalHandleRef.current);};}, []);return (<><View style={styles.swiperWrap}><Animated.Viewref={animatedViewRef}style={{width: deviceWidth * swiperList.length,flex: 1,flexDirection: 'row',transform: [{translateX: pan}],onStartShouldSetResponderCapture: () => false, // 禁止拦截触摸事件}}{...panResponder.panHandlers}>{swiperList.map((item, index) => (<View key={'swiperItem' + index} style={{width: deviceWidth}}><View style={styles.swiperItem}><Text>item {item.id}</Text></View></View>))}</Animated.View></View></>);
};const styles = StyleSheet.create({swiperWrap: {borderColor: 'red',borderWidth: pxToPd(1),borderStyle: 'solid',width: '100%',height: pxToPd(400),},swiperItem: {borderColor: 'red',borderWidth: pxToPd(1),borderStyle: 'solid',borderRadius: pxToPd(12),width: '93.6%',marginLeft: '3.2%',height: '100%',},
});export default TestSwiper;
http://www.lryc.cn/news/322463.html

相关文章:

  • Jetson入坑记实
  • 算法系列--递归
  • 【JS】替换文本为emjio表情
  • Solr完结版
  • 外包干了5天,技术退步明显。。。。
  • Cronos zkEVM 基于 Covalent Network(CQT)数据可用性 API,推动其 Layer2 DeFi 生态更好地发展
  • 基于SpringBoot的高校办公室行政事务管理系统
  • Linux系统及操作 (04)
  • 粒子群算法 - 目标函数最优解计算
  • 关于MySQL数据库的学习3
  • 笔试题——得物春招实习
  • 动手做简易版俄罗斯方块
  • 【极简无废话】open3d可视化torch、numpy点云
  • C语言经典算法-6
  • 【计算机考研】杭电 vs 浙工大 怎么选?
  • 激活函数
  • 使用Jackson进行 JSON 序列化和反序列化
  • Linux/Uinx 系统编程:定时器以及时钟同步
  • (Ubuntu中调用相机花屏)Astra plus深度相机--rgb彩色图像花屏解决方法之一
  • iPaaS平台能帮助企业解决什么问题?
  • 数学建模(灰色关联度 python代码 案例)
  • 【DP】第十四届蓝桥杯省赛C++ B组《接龙数列》(C++)
  • 文件包含漏洞(input、filter、zip)
  • 使用iconv解决Linux/Ubuntu/Debian中gb2312中文文档乱码问题
  • 图论中的最小生成树:Kruskal与Prim算法深入解析
  • uniapp 之 实现商品详情的锚点跳转(类似京东商品详情-点击顶部按钮跳转的对应的页面的内容区域)
  • PPT好看配色
  • 微信小程序执行环境(微信端)与浏览器环境有何不同
  • Java小项目--满汉楼
  • 微信怎样群发更高效?