react native中如何实现tab切换页面以及页面可以左右滑动效果

react native中如何实现tab切换页面以及页面可以左右滑动效果

效果示例图

主体代码

复制代码
import React, {useRef, useState} from 'react';
import {
  View,
  ScrollView,
  Text,
  StyleSheet,
  Dimensions,
  Animated,
} from 'react-native';
import {pxToPd} from '../../common/js/device';
import MatchTab from './matchTab';

const TabOne = () => {
  return (
    <>
      <View style={styles.page}>
        <Text style={styles.title}>全部</Text>
      </View>
    </>
  );
};
const TabTwo = () => {
  return (
    <>
      <View style={styles.page}>
        <Text style={styles.title}>新闻</Text>
      </View>
    </>
  );
};
const TabThree = () => {
  return (
    <>
      <View style={styles.page}>
        <Text style={styles.title}>资讯</Text>
      </View>
    </>
  );
};
const TabFour = () => {
  return (
    <>
      <View style={styles.page}>
        <Text style={styles.title}>小说</Text>
      </View>
    </>
  );
};

const TestExample = () => {
  const [tabCode, setTabCode] = useState(2);
  const [tabList, setTabList] = useState([
    {
      name: '全部',
      code: 2,
    },
    {
      name: '新闻',
      code: 3,
    },
    {
      name: '资讯',
      code: 8,
    },
    {
      name: '小说',
      code: 11,
    },
  ]);
  const scrollViewRef = useRef(null);
  let currentIndexRef = useRef(0);

  // 滚动视图的水平偏移量
  const scrollX = useState(new Animated.Value(0))[0];

  // 页面切换时的处理函数
  const handlePageChange = event => {
    const offsetX = event.nativeEvent.contentOffset.x;
    const pageIndex = Math.round(offsetX / Dimensions.get('window').width);
    currentIndexRef.current = pageIndex;
    setTabCode(() => tabList[currentIndexRef.current].code);
  };
  //tab切换时的处理函数
  const tabChangeHandle = row => {
    setTabCode(() => row.status);
    let subscript = tabList.findIndex(item => item.code == row.status);
    scrollViewRef.current.scrollTo({
      x: subscript * Dimensions.get('window').width,
      animated: false, //去掉过渡效果
    });
  };

  return (
    <>
      {/* tab */}
      <View style={styles.tabWrap}>
        <MatchTab list={tabList} code={tabCode} onClick={tabChangeHandle} />
      </View>
      <View style={styles.container}>
        <ScrollView
          ref={scrollViewRef}
          horizontal
          pagingEnabled
          showsHorizontalScrollIndicator={false}
          onScroll={Animated.event(
            [{nativeEvent: {contentOffset: {x: scrollX}}}],
            {
              useNativeDriver: false,
              listener: handlePageChange,
            },
          )}
          scrollEventThrottle={16}>
          <TabOne />
          <TabTwo />
          <TabThree />
          <TabFour />
        </ScrollView>
      </View>
    </>
  );
};
const styles = StyleSheet.create({
  // tab
  tabWrap: {
    width: '100%',
    height: pxToPd(80),
  },
  container: {
    flex: 1,
  },
  page: {
    borderColor: 'red',
    borderStyle: 'solid',
    borderWidth: pxToPd(1),
    width: Dimensions.get('window').width,
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
  },
});

export default TestExample;
相关推荐
程序员大阳6 小时前
副队长JavaScript教程(50)-DOM:网页开发的起点
javascript·dom·es·节点·概念·document·关系
香芋芋圆11 小时前
iD-editor 详解|OSM官方在线编辑器,基于D3.js的轻量地图编辑器
开发语言·javascript·编辑器
晗夜未央13 小时前
任务队列反复失败,先分清重试、阻塞和结果待核对
开发语言·javascript
jktantan13 小时前
每个节点 41 字节:把一棵百万节点树拆进 14 个 typed array
前端·javascript·vue.js·算法·typescript
我命由我1234514 小时前
访客系统形式(有用户概念、无用户概念)
java·开发语言·前端·javascript·python·产品运营·产品经理
程序员大阳15 小时前
副队长JavaScript教程(65)-详解JSON:轻量级数据交换格式
javascript·json·序列化·反序列化·stringify·parse
paopaokaka_luck16 小时前
基于springboot+vue的益暖微光公益服务平台(DeepSeek公益助手、善款信息追溯、志愿服务积分闭环、ECharts运营分析、活动状态自动流转)
java·前端·javascript·spring boot·mysql·架构·echarts
栀椩16 小时前
Electron 内嵌页面跨域问题(CORS/PNA)解决全记录
前端·javascript·electron
SEO_juper17 小时前
Chrome 扩展一键查看当前页面 SEO 信息:不用切页面,点一下全出来
前端·javascript·chrome
Highcharts.js17 小时前
CSUN 2026|Highcharts无障碍数据与AI分享
javascript·人工智能·数据分析·highcharts·图表开发