基于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.View
          ref={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;


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/490175.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小目标检测篇 | YOLOv8改进之GSConv + Slim Neck提升小目标检测效果

前言:Hello大家好,我是小哥谈。在文章中,作者提出了一种新方法GSConv来减轻模型的复杂度并保持准确性。GSConv可以更好地平衡模型的准确性和速度。并且,提供了一种设计范式Slim Neck,以实现检测器更高的计算成本效益。实验过程中,与原始网络相比,改进方法获得了最优秀的…

GDAl 之绘制栅格图像的大致直方图和精准直方图(8)

gdal的绘制大致直方图是仅查看概览或者抽样像素的一个子集 import os from osgeo import gdal import matplotlib.pyplot as plt import numpy as np# Dont forget to change directory. os.chdir(rD:\DeskTop\learn_py_must\Learn_GDAL\osgeopy-data\osgeopy-data\Switzerlan…

基于Selenium+Python的web自动化测试框架!

简介&#xff1a; 本文将详细介绍如何运用Python结合Selenium WebDriver库搭建web自动化测试框架。 一、什么是Selenium&#xff1f; Selenium是一个基于浏览器的自动化测试工具&#xff0c;它提供了一种跨平台、跨浏览器的端到端的web自动化解决方案。Selenium主要包括三部分…

音视频处理 - 音频概念详解,码率,采样率,位深度,声道,编码

1. 音频采样 与视频不同&#xff0c;音频的最小单位不是一帧&#xff0c;而是一个采样。 采样是当前一刻声音的声音样本&#xff0c;样本需要经过数字转换才能存储为样本数据。 真实声音是连续的&#xff0c;但是在计算机中&#xff0c;声音是离散且均匀的声音样本。 2. 位深…

ER图与关系模型

1.设某商业集团数据库中有三个实体集。 “公司”实体集&#xff0c;属性有公司编号、公司名、地址等&#xff1b; “仓库”实体集&#xff0c;属性有仓库编号、仓库名、地址等&#xff1b; “职工”实体集&#xff0c;属性有职工编号、姓名、性别等。公司与仓库间存在“隶属…

《被讨厌的勇气》读书思考笔记 (好书推荐)

《被讨厌的勇气》是一本由日本心理学家岸见一郎和奥冈昌高合著的畅销心理成长书籍。这本书基于心理学家阿尔弗雷德阿德勒的思想&#xff0c;介绍了“自我决定心理学”的观点&#xff0c;探讨了人们如何克服害怕失败&#xff0c;勇敢追求自己真正想要的生活。这本书在心理学、自…

HCIP的学习(4)

GRE和MGRE VPN---虚拟专用网络。指依靠ISP&#xff08;运营商&#xff09;或其他公有网络基础设施上构建的专用的安全数据通信网络。该网络是属于逻辑上的。​ 核心机制—隧道机制&#xff08;封装技术&#xff09; GRE—通用路由封装 ​ 三层隧道技术&#xff0c;并且是属于…

Git基础(23):Git分支合并实战保姆式流程

文章目录 前言准备正常分支合并1. 创建两个不冲突分支2. 将dev合并到test 冲突分支合并1. 制造分支冲突2. 冲突合并 前言 Git分支合并操作 准备 这里先在Gitee创建了一个空仓库&#xff0c;方便远程查看内容。 正常分支合并 1. 创建两个不冲突分支 &#xff08;1&#xf…

Tableau项目案例-网上超市运营分析

一、数据简要介绍 超市运营分析.xlsx 1、客户分析 交易次数统计 购买次数即购买频率,是指消费者在一定时期内购买某种或某类商品的次数。 用tableau打开excel文件 双击城市字段,会显出出一个地图 类别字段也拖到筛选器上,如上操作相同

AI论文速读 | 具有时间动态的路网语义增强表示学习

论文标题&#xff1a; Semantic-Enhanced Representation Learning for Road Networks with Temporal Dynamics 作者&#xff1a; Yile Chen&#xff08;陈亦乐&#xff09; ; Xiucheng Li&#xff08;李修成&#xff09;; Gao Cong&#xff08;丛高&#xff09; ; Zhifeng Ba…

管理能力学习笔记四:团队发展四阶段

组建期 管理方式 动荡期 领导方式 规范期 管理方式 高产期 管理方式 高产期的注意点

FL Studio21.2.3最新中文编曲音乐制作软件新版本功能介绍

一、前言 随着科技的发展&#xff0c;越来越多的人开始尝试自己创作音乐。然而&#xff0c;传统的音乐制作过程复杂繁琐&#xff0c;需要昂贵的硬件设备和专业的知识技能。那么&#xff0c;有没有一款软件可以让普通人也能轻松地制作出专业级别的音乐作品呢&#xff1f;答案就…

什么是 ECMAScript,它与 JavaScript 有何不同

什么是 ECMAScript? 关于 JavaScript](https://cloudaffle.com/history-of-javascript/)的[历史以及它是如何产生的,有一个完整的故事。长话短说,ECMAScript 中的 ECMA 是指欧洲计算机制造商协会,早在 1997 年就向该协会提交了 JavaScript 1.1 进行标准化。创建了一个技术委员…

机器学习(二)

线性模型: 离散转为连续的变换: 检查是否有“序”的变化&#xff0c;若有“序”&#xff0c;则连续化&#xff1b;否则&#xff0c;转化为k维向量 最小二乘解: 多元线性回归: 广义线性模型: 线性判别分析: 由于将样例投影到一条直线(低维空间)&#xff0c;因此也被视为一种&q…

洛谷1803

P1803 凌乱的yyy / 线段覆盖 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 所需知识&#xff1a;贪心 本来还想用dfs bfs搜索来一点一点做的&#xff0c;看到了大佬的思路之后&#xff0c;直接orz了 整体思路&#xff1a;因为要想尽可能的多参加比赛&#xff0c;所以越早结…

MySQL 经典练习 50 题 (记录)

前言&#xff1a; 记录一下sql学习&#xff0c;仅供参考基本都对了&#xff0c;不排除有些我做的太快做错了。里面sql不存在任何sql优化操作&#xff0c;只以完成最后输出结果为目的&#xff0c;包含我做题过程和思路最后一行才是结果。 1.过程: 1.1.插入数据 /* SQLyog Ul…

《论文阅读》TSAM:一个因果情绪蕴含的双流注意模型 COLING 2022

《论文阅读》TSAM:一个因果情绪蕴含的双流注意模型 前言简介方法整体流程图上下文语句表示Two-Stream Attention Model(TSAM)原因预测实验结果前言 亲身阅读感受分享,细节画图解释,再也不用担心看不懂论文啦~ 无抄袭,无复制,纯手工敲击键盘~ 今天为大家带来的是《TSAM:…

Python 指南-最短路径(Dijkstra 算法):

Dijkstra 算法可在 Python 库 OSMNX 中实现&#xff0c;可用于查找两个位置之间按距离或时间加权的最短路径。该算法使用 OpenStreetMap (OSM) 网络来驾驶、步行或骑自行车&#xff0c;并在后台使用 Python 库 NETWORKX 查找路线。 编码练习 正如我提到的&#xff0c;我将做一…

MySQL 8.0.35 企业版开启审计audit log功能

一、系统环境和要求 在MySQL中&#xff0c;开启日志审计可以记录数据库的操作日志&#xff0c;包括修改、删除、插入等操作。这对于追踪和分析数据库的使用情况以及排查潜在的安全问题非常有帮助。本文将详细介绍如何开启MySQL的日志审计功能。 操作系统&#xff1a;Ubuntu 20…

距离AI PC起飞,还差了点什么?

作者 | 张未 来源 | 洞见新研社 PC行业也没有逃过万物皆可AI的真香定律。 英伟达在前喊出AI PC的口号后&#xff0c;一众PC厂商纷纷加码这一最新概念&#xff0c;有关AI PC的讨论点燃了PC市场。 最直观的变化就是&#xff0c;全球PC市场终于止住了颓势&#xff0c;打破了七连…