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;
相关推荐
暴富的Tdy38 分钟前
【CryptoJS库AES加密】
前端·javascript·vue.js
℘团子এ1 小时前
js和html中,将Excel文件渲染在页面上
javascript·html·excel
胡西风_foxww3 小时前
【es6复习笔记】Promise对象详解(12)
javascript·笔记·es6·promise·异步·回调·地狱
秃头女孩y3 小时前
【React中最优雅的异步请求】
javascript·vue.js·react.js
dlnu20152506227 小时前
ssr实现方案
前端·javascript·ssr
轻口味8 小时前
命名空间与模块化概述
开发语言·前端·javascript
前端小小王9 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发9 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
真滴book理喻12 小时前
Vue(四)
前端·javascript·vue.js