效果示例图
示例代码
/* 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) => (<Viewstyle={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}><ImageBackgroundstyle={styles.ruleBlockTitleBg}source={require('../../common/imgs/main_ruleDetail_titleBg.png')}><Textstyle={styles.ruleBlockTitleTxt}ellipsizeMode="middle"numberOfLines={1}>{item?.name}</Text></ImageBackground></View>{/* 装饰图 */}<Imagestyle={styles.ruleBlockDecorate}source={require('../../common/imgs/main_ruleDetail_tips.png')}/>{/* 列表内容-start */}{item?.data?.map((subitem, subindex) => (<Viewstyle={styles.ruleBlockSubCon}key={'ruleBlockSubCon-' + subindex}>{/* 二级标题 */}<Viewstyle={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}><HTMLcontentWidth={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)}><Textstyle={{width: '100%',height: pxToPd(60),lineHeight: pxToPd(60),textAlign: 'center',}}>{item?.name}</Text></TouchableOpacity>{item?.data?.map(subitem => (<TouchableOpacity onPress={() => goSkipHandle(subitem)}><Textstyle={{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;