基于react native的锚点

news2024/12/28 5:00:53

基于react native的锚点

    • 效果示例图
    • 示例代码

效果示例图

在这里插入图片描述

示例代码

/* eslint-disable react-native/no-inline-styles */
import React, { useEffect, useRef, useState } from 'react';
import {
  Image,
  ImageBackground,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import HTML from 'react-native-render-html';
import { pxToPd, pxToPdT } from '../../common/js/device';
const desc =
  '<p>如违反《赛事须知》中的内容,可能使我受到警告、判负、丧失比赛资格/获奖资格以及禁赛等赛事处罚,亦可能被请离现场。如违反《赛事须知》中的内容,可能使我受到警告、判负、丧失比赛资格/获奖资格以及禁赛等赛事处罚,亦可能被请离现场。如违反《赛事须知》中的内容,可能使我受到警告、判负、丧失比赛资格/获奖资格以及禁赛等赛事处罚,亦可能被请离现场。</p>';

const tempData = [
  {
    id: 1,
    name: '工藤新一一级标题',
    data: [
      {
        id: 2,
        name: '二级标题002',
        content: desc,
      },
      {
        id: 3,
        name: '二级标题003',
        content: desc,
      },
      {
        id: 4,
        name: '二级标题004',
        content: desc,
      },
    ],
  },
  {
    id: 5,
    name: '毛利兰一级标题',
    data: [
      {
        id: 6,
        name: '二级标题006',
        content: desc,
      },
      {
        id: 7,
        name: '二级标题007',
        content: desc,
      },
      {
        id: 8,
        name: '二级标题008',
        content: desc,
      },
    ],
  },
  {
    id: 9,
    name: '流放了一级标题',
    data: [
      {
        id: 10,
        name: '二级标题0010',
        content: desc,
      },
      {
        id: 11,
        name: '二级标题0011',
        content: desc,
      },
      {
        id: 12,
        name: '二级标题0012',
        content: desc,
      },
    ],
  },
];

const TestCatalog = () => {
  const scrollViewRef = useRef(null);

  //列表数据
  const [dataList, setDataList] = useState([]);

  const viewRefs = useRef([]);
  const menuRef = useRef([]);

  const initFunction = () => {
    setDataList(() => tempData);
  };

  const goSkipHandle = row => {
    let tempArr = menuRef.current;
    tempArr.some(item => {
      if (item.id === row.id) {
        scrollViewRef.current.scrollTo({ y: item?.y - 100, animated: true });
      }
    });
  };

  const getPositionValue = (row, y) => {
    let tempMenu = [...menuRef.current];
    let tempItem = row;
    if (tempItem.y === undefined) {
      tempItem.y = y;
    }
    tempMenu.push(row);
    menuRef.current = tempMenu;
  };

  useEffect(() => {
    initFunction();
    return () => {};
  }, []);
  return (
    <>
      <View style={{ flex: 1 }}>
        <ScrollView ref={scrollViewRef}>
          {/* 列表内容 */}
          {dataList?.map((item, index) => (
            <View
              style={styles.ruleBlock}
              key={'ruleBlock-' + index}
              ref={ref => {
                viewRefs.current[item?.id] = ref;
              }}
              onLayout={() => {
                if (viewRefs.current[item?.id]) {
                  viewRefs.current[item?.id].measure(
                    (x, y, width, height, pageX, pageY) => {
                      console.log(x, y, width, height, pageX);
                      getPositionValue(item, pageY);
                    },
                  );
                }
              }}>
              {/* 一级标题 */}
              <View style={styles.ruleBlockTitle}>
                <ImageBackground
                  style={styles.ruleBlockTitleBg}
                  source={require('../../common/imgs/main_ruleDetail_titleBg.png')}>
                  <Text
                    style={styles.ruleBlockTitleTxt}
                    ellipsizeMode="middle"
                    numberOfLines={1}>
                    {item?.name}
                  </Text>
                </ImageBackground>
              </View>
              {/* 装饰图 */}
              <Image
                style={styles.ruleBlockDecorate}
                source={require('../../common/imgs/main_ruleDetail_tips.png')}
              />
              {/* 列表内容-start */}
              {item?.data?.map((subitem, subindex) => (
                <View
                  style={styles.ruleBlockSubCon}
                  key={'ruleBlockSubCon-' + subindex}>
                  {/* 二级标题 */}
                  <View
                    style={styles.ruleBlockSubTitle}
                    ref={ref => {
                      viewRefs.current[subitem?.id] = ref;
                    }}
                    onLayout={() => {
                      if (viewRefs.current[subitem?.id]) {
                        viewRefs.current[subitem?.id].measure(
                          (x, y, width, height, pageX, pageY) => {
                            console.log(x, y, width, height, pageX);
                            getPositionValue(subitem, pageY);
                          },
                        );
                      }
                    }}>
                    <Text style={styles.ruleBlockSubTitleTxt}>
                      {subitem?.name}
                    </Text>
                  </View>
                  {/* 内容 */}
                  <View style={{ width: '100%', height: pxToPd(24) }} />
                  <View style={styles.ruleBlockSubDesc}>
                    <HTML
                      contentWidth={100}
                      source={{
                        html: `<div>${subitem?.content}</div>`,
                      }}
                    />
                  </View>
                </View>
              ))}

              {/* 列表内容-end*/}

              <View style={{ width: '100%', height: pxToPd(40) }} />
            </View>
          ))}
        </ScrollView>
      </View>
      <View style={styles.modalWrap}>
        {dataList?.map(item => (
          <View>
            <TouchableOpacity onPress={() => goSkipHandle(item)}>
              <Text
                style={{
                  width: '100%',
                  height: pxToPd(60),
                  lineHeight: pxToPd(60),
                  textAlign: 'center',
                }}>
                {item?.name}
              </Text>
            </TouchableOpacity>
            {item?.data?.map(subitem => (
              <TouchableOpacity onPress={() => goSkipHandle(subitem)}>
                <Text
                  style={{
                    width: '100%',
                    height: pxToPd(60),
                    lineHeight: pxToPd(60),
                    textAlign: 'center',
                  }}>
                  {subitem?.name}
                </Text>
              </TouchableOpacity>
            ))}
          </View>
        ))}
      </View>
    </>
  );
};

const styles = StyleSheet.create({
  detailBg: {
    width: '100%',
    height: pxToPd(1624),
  },
  container: {
    flex: 1,
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
  },
  //内容
  ruleBlock: {
    width: '93.6%',
    marginLeft: '3.2%',
    borderRadius: pxToPd(40),
    backgroundColor: '#fff',
    minHeight: pxToPd(400),
    position: 'relative',
    marginBottom: pxToPd(97),
  },
  ruleBlockTitle: {
    width: pxToPd(533),
    height: pxToPd(86),
    marginLeft: -pxToPd(8),
    marginTop: -pxToPd(8),
  },
  ruleBlockTitleBg: {
    width: '100%',
    height: '100%',
  },
  ruleBlockTitleTxt: {
    height: pxToPd(86),
    width: pxToPd(500),
    lineHeight: pxToPd(86),
    fontSize: pxToPdT(32),
    fontWeight: 'bold',
    color: '#fff',
    marginLeft: pxToPd(19),
  },
  ruleBlockDecorate: {
    width: pxToPd(160),
    height: pxToPd(193),
    position: 'absolute',
    top: -pxToPd(14),
    right: -pxToPd(1),
  },
  ruleBlockSubCon: {
    width: '93.6%',
    marginLeft: '3.2%',
    marginTop: pxToPd(42),
  },
  ruleBlockSubTitle: {
    width: '100%',
  },
  ruleBlockSubTitleTxt: {
    width: '100%',
    fontSize: pxToPdT(30),
    fontWeight: 'normal',
    color: '#333',
    textAlign: 'center',
  },
  ruleBlockSubDesc: {
    width: '100%',
  },
  modalWrap: {
    borderRadius: pxToPd(24),
    width: pxToPd(300),
    position: 'absolute',
    top: 100,
    right: 20,
    backgroundColor: '#f5f5f5',
    flexDirection: 'column',
  },
});

export default TestCatalog;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎么选到好用的运动耳机?这五款年度精选骨传导耳机非常好用!

在过去的两年里&#xff0c;骨传导耳机逐渐被大众的所熟知。可能毕竟长时间使用音量过大的传统入耳式耳机&#xff0c;多多少少会对我们的听力健康构成威胁。所以很多人就想找一款不伤耳朵的耳机。然后就了解到了骨传导耳机&#xff0c;所以就会延伸出这些问题——骨传导耳机好…

【Canvas与密铺】90年代马赛克密铺效果 1920x1080

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>20世纪90年代马赛克瓷砖效果1920x1080</title><style type&…

美创获评CNVD年度原创漏洞发现贡献单位!

9月10日&#xff0c;第21届中国网络安全年会暨网络安全协同治理分论坛在广州成功举办。会上&#xff0c;美创科技首次获评“CNVD年度原创漏洞发现贡献单位”。 美创科技依托第59号安全实验室&#xff0c;专注数据安全技术和攻防研究。凭借深厚的技术积累与优势&#xff0c;被遴…

SEAFARING靶场渗透

一.SQL注入漏洞 1.输入id1 -- 下方出现数据说明闭合成功 2.测试得出数据库有三列 3.三处都是回显点 4.联合查询爆出库名 5.查表名 ?id-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schematest-- 6.查字段名 ?id-1 union sele…

vscode spring boot项目编辑yaml不自动提示补全如何解决

文章目录 properties能够自动弹出提示但是YAML文件就不会自动弹出提示ctrl空格不出提示的解决办法 properties能够自动弹出提示 但是YAML文件就不会自动弹出提示 只是不会自动弹出来而已&#xff0c;按ctrl空格即可解决 ctrl空格不出提示的解决办法 如果按ctrl空格没有用 …

WGCLOUD使用指南 - 自动计算磁盘剩余空间的可使用天数

WGCLOUD是一款免费开源的运维监控软件&#xff0c;性能优秀&#xff0c;部署简单&#xff0c;轻巧使用&#xff0c;支持大部分的Linux和Windows、安卓、MacOS等平台安装部署 最近发布的新版本&#xff0c;WGCLOUD新增了可以自动计算每个磁盘剩余空间的可使用天数&#xff0c;主…

你还在为写PPT而烦恼吗,Kimi一键帮你生成PPT

PPT已经成为我们日常工作和学习中不可或缺的一部分。无论是企业会议、学术报告还是产品展示&#xff0c;一个精心制作的PPT都能有效提升信息传递的效率和质量。然而&#xff0c;制作一个既美观又专业的PPT并非易事&#xff0c;它需要耗费大量的时间和精力。幸运的是&#xff0c…

中伟视界:皮带跑偏检测算法及其实现模型和判断方法

皮带输送机广泛应用于矿山、港口、化工等行业&#xff0c;其正常运行对生产效率和安全性至关重要。皮带跑偏是输送机常见的故障之一&#xff0c;可能导致物料撒落、设备损坏&#xff0c;甚至引发安全事故。为了有效监测和预防皮带跑偏&#xff0c;现代技术利用多种算法模型和判…

还有哪个地方能申请到免费一年期的SSL证书?

SSL证书是互联网中用于加密网站与访问者之间数据传输的安全证书。它通过数字签名确认网站的真实身份&#xff0c;确保数据传输的私密性、完整性和服务器身份的真实性&#xff0c;有效防止数据在传输过程中被窃取或篡改&#xff0c;是保障网站安全性的重要手段。 永久免费SSL证…

20240914 每日AI必读资讯

刚刚&#xff0c;OpenAI震撼发布o1大模型&#xff01;强化学习突破LLM推理极限 - OpenAI o1模型需要简单、直接的提示&#xff0c;而非复杂的指导。 - 避免使用思路链提示&#xff0c;因为o1模型已经具备内部推理能力。 - 使用分隔符来明确模型解析的部分&#xff0c;并限制…

绝佳的知乎展示形式,助力品牌信息全面曝光

知乎作为国内领先的中文互联网问答社区&#xff0c;汇聚了亿万高价值用户&#xff0c;其独特的内容生态与深度互动机制&#xff0c;为品牌提供了前所未有的营销舞台。云衔科技作为数字营销领域的佼佼者&#xff0c;携手知乎&#xff0c;为您量身打造了一套集信息流广告、知广告…

Debian11之DolphinScheduler使用

登录 默认用户名和密码 admin/dolphinscheduler123 http://192.168.111.180:12345/dolphinscheduler/ui基础配置 创建队列【admin用户下】 创建Worker分组管理【admin用户下】 关联某个工作节点服务器&#xff0c;创建项目的时候会指定Worker分组&#xff0c;这个配置决定了…

反思:我们如何实现自我的凤凰涅槃和卓越的人生?

目录 什么是凤凰涅槃&#xff1f; 一、起源与含义 二、文化解读 三、象征意义 ​编辑 我们如何实现自我的凤凰涅槃和卓越的人生&#xff1f; 一、心态调整 二、行为改变 三、持续学习与成长 四、具体行动步骤 什么是凤凰涅槃&#xff1f; 凤凰涅槃是一个具有深…

C++三大特性之一:多态篇【创作不易,还请点赞+收藏❤】

一、多态的概念 从我们学习C的时候&#xff0c;想必或多或少都听说过&#xff0c;C的三大特性&#xff1a;封装、继承&#xff0c;多态&#xff1b;而今天我们将学习多态&#xff0c;多态简单来讲&#xff0c;就是多种形式。多态分为&#xff0c;编译时多态——静态多态&#…

Spark-ShuffleWriter-UnsafeShuffleWriter

一、上下文 《Spark-ShuffleWriter》中对ShuffleWriter的获取、分类和写入做了简单的分析&#xff0c;下面我们对其中的UnsafeShuffleWriter做更详细的学习 二、构建UnsafeShuffleWriter public UnsafeShuffleWriter(BlockManager blockManager,TaskMemoryManager memoryMana…

利用Packet tracer搭建简单的网络并进行通信验证

利用Packet tracer搭建一个基本的网络通信&#xff1a; 1&#xff1a;创建网络组件 先去创建几个终端设备&#xff0c;然后再去创建一个交换机 布局完成的界面是&#xff1a; 2&#xff1a;连接组件 用指定的线进行连接交换机和PC机 全部连接的结果是: 3&#xff1a;配置PC机…

桥接网络设置多用户lxd容器

文章目录 前言配置宿主机网络固定内核版本安装 lxd、zfs 及 bridge-utils安装宿主机显卡驱动lxd 初始化创建容器模板安装容器显卡驱动复制容器 前言 使用桥接网络配置 lxd 有个好处&#xff0c;就是每个用户都可以在该局域网下有一个自己独立的 IP&#xff0c;该 IP 的端口可以…

崩坏星穹铁道PC端2.5版本剧情、奖励攻略 用GameViewer远程帮手机减负 随时畅玩星铁PC端

《崩坏&#xff1a;星穹铁道》2.5版本「碧羽飞黄射天狼」在9月10开启&#xff01;上半卡池有五星角色飞霄、知更鸟、卡芙卡、黑天鹅四位角色&#xff0c;还有2.5版本的新剧情&#xff0c;这一次崩铁上线送10连和 1000星琼等其他材料。由于游戏包体过大&#xff0c;不少玩家都选…

web群集--nginx实现重定向与重写操作的详细配置过程详与案例展示

文章目录 前言什么是重定向&#xff1f;重定向能做什么&#xff1f;何时需要重定向功能&#xff1f;nginx通过什么来实现重定向和重写操作的&#xff1f;nginx的重定向和重写有什么区别&#xff1f;案例展示重定向1.将所有对将所有对http://test. com 的访问重定向到http://www…

【iOS】push和present的区别

【iOS】push和present的区别 文章目录 【iOS】push和present的区别前言pushpop presentdismiss简单小demo来展示dismiss和presentdismiss多级 push和present的区别区别相同点 前言 在iOS开发中&#xff0c;我们经常性的会用到界面的一个切换的问题&#xff0c;这里我们需要理清…