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;
相关推荐
海的诗篇_1 小时前
前端开发面试题总结-原生小程序部分
前端·javascript·面试·小程序·vue·html
黄瓜沾糖吃3 小时前
大佬们指点一下倒计时有什么问题吗?
前端·javascript
温轻舟3 小时前
3D词云图
前端·javascript·3d·交互·词云图·温轻舟
浩龙不eMo3 小时前
✅ Lodash 常用函数精选(按用途分类)
前端·javascript
爱分享的程序员3 小时前
前端面试专栏-算法篇:17. 排序算法
前端·javascript·node.js
pe7er4 小时前
使用 Vue 官方脚手架创建项目时遇到 Node 18 报错问题的排查与解决
前端·javascript·vue.js
pe7er4 小时前
使用 types / typings 实现全局 TypeScript 类型定义,无需 import/export
前端·javascript·vue.js
islandzzzz4 小时前
(第二篇)HMTL+CSS+JS-新手小白循序渐进案例入门
前端·javascript·css·html
喝拿铁写前端5 小时前
前端实战优化:在中后台系统中用语义化映射替代 if-else,告别魔法数字的心智负担
前端·javascript·架构
超人不会飛5 小时前
就着HTTP聊聊SSE的前世今生
前端·javascript·http