From a70b7437d7979b8a7b4db72a9996cb120452af31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E6=B5=A9?= <303527871@qq.com> Date: Sat, 21 Sep 2024 12:32:29 +0800 Subject: [PATCH] fix: remove useless parameters --- src/components/PageView/PageView.tsx | 24 ++++++++++----- src/components/TabBar/TabBar.tsx | 44 +++++++++++++++++++++++----- src/components/TabBar/type.ts | 1 + src/components/TabView/TabView.tsx | 32 ++++++++++++++++---- 4 files changed, 80 insertions(+), 21 deletions(-) diff --git a/src/components/PageView/PageView.tsx b/src/components/PageView/PageView.tsx index 115e60a..85de894 100644 --- a/src/components/PageView/PageView.tsx +++ b/src/components/PageView/PageView.tsx @@ -31,7 +31,7 @@ const PageView = forwardRef((props, ref) => { const pageMove = useSharedValue(-initialPage * contentSize); const offset = useSharedValue(0); - const currentPage = useSharedValue(initialPage); + const currentIndex = useSharedValue(initialPage); const pageState = useSharedValue('idle'); const pageSelected = (nextPage: number) => { @@ -47,18 +47,28 @@ const PageView = forwardRef((props, ref) => { }; const setPage = (index: number) => { + if (index < 0 || index >= pageSize) { + throw new Error('setPage can only handle index [0, pageSize]'); + } + moveTo(index); }; const setPageWithoutAnimation = (index: number) => { + if (index < 0 || index >= pageSize) { + throw new Error( + 'setPageWithoutAnimation can only handle index [0, pageSize]' + ); + } + pageMove.value = -index * contentSize; - currentPage.value = index; + currentIndex.value = index; pageState.value = 'idle'; runOnJS(pageSelected)(index); }; const getCurrentPage = () => { - return currentPage.value; + return currentIndex.value; }; useImperativeHandle( @@ -92,7 +102,7 @@ const PageView = forwardRef((props, ref) => { { duration: DURATION }, () => { const nextPage = Math.abs(Math.round(pageMove.value / contentSize)); - currentPage.value = nextPage; + currentIndex.value = nextPage; pageState.value = 'idle'; runOnJS(pageSelected)(nextPage); } @@ -102,7 +112,7 @@ const PageView = forwardRef((props, ref) => { const panGesture = Gesture.Pan() .activeOffsetX([-10, 10]) .onTouchesDown((event, stateManager) => { - if (currentPage.value === 0 && gestureBack) { + if (currentIndex.value === 0 && gestureBack) { const allTouches = event.allTouches[0]; if (allTouches.x <= 35) { stateManager.fail(); @@ -134,8 +144,8 @@ const PageView = forwardRef((props, ref) => { const willToPage = Math.abs(Math.round(dest / contentSize)); const toValue = clamp( willToPage, - currentPage.value - 1, - currentPage.value + 1 + currentIndex.value - 1, + currentIndex.value + 1 ); moveTo(toValue); diff --git a/src/components/TabBar/TabBar.tsx b/src/components/TabBar/TabBar.tsx index fea3a98..d6ef707 100644 --- a/src/components/TabBar/TabBar.tsx +++ b/src/components/TabBar/TabBar.tsx @@ -1,7 +1,15 @@ -import React, { useMemo, useRef, useState } from 'react'; +import React, { + forwardRef, + useEffect, + useImperativeHandle, + useMemo, + useRef, + useState, +} from 'react'; import { View, ScrollView, LayoutChangeEvent, StyleSheet } from 'react-native'; import TabBarItem from './TabBarItem'; import Animated, { + runOnUI, useAnimatedStyle, useSharedValue, withTiming, @@ -11,7 +19,11 @@ import Separator from './Separator'; import { TabBarProps, TabBarItemLayout } from './type'; import { useVerifyProps } from './hook'; -const TabBar: React.FC = (props) => { +interface TabBarRef { + setTab: (index: number) => void; +} + +const TabBar = forwardRef((props, ref) => { const { tabs, style, @@ -32,15 +44,22 @@ const TabBar: React.FC = (props) => { contentSize, } = useVerifyProps(props); - const [currentIndex, setCurrentIndex] = useState(initialTab); const sliderOffset = useSharedValue(0); const scrollSize = useRef(0); const scrollRef = useRef(null); const layouts = useRef([]).current; const sliderWidth = useRef(defalutSliderWidth); + useImperativeHandle( + ref, + () => ({ + setTab: handleOnPress, + }), + [] + ); + const handleOnPress = (index: number) => { - setCurrentIndex(index); + // setCurrentIndex(index); calculateSliderOffset(index); onPress && onPress(index); }; @@ -48,8 +67,9 @@ const TabBar: React.FC = (props) => { const onTabBarItemLayout = (index: number, layout: TabBarItemLayout) => { layouts[index] = layout; const length = layouts.filter((layout) => layout.width > 0).length; + if (length === tabs.length) { - calculateSliderOffset(currentIndex); + calculateSliderOffset(initialTab); } }; @@ -64,7 +84,14 @@ const TabBar: React.FC = (props) => { const calculateSliderOffset = (index: number) => { 'worklet'; + if (index < 0 || index >= tabs.length) { + throw new Error( + 'calculateSliderOffset can only handle index [0, tabs.length - 1]' + ); + } + const { x, y, width, height } = layouts[index]; + const toValue = x + (width - sliderWidth.current) / 2; if (toValue > contentSize / 2) { scrollRef.current && @@ -104,12 +131,13 @@ const TabBar: React.FC = (props) => { scrollEnabled={scrollEnabled} onContentSizeChange={onContentSizeChange} contentContainerStyle={styles.contentContainerStyle} + scrollEventThrottle={16} showsHorizontalScrollIndicator={false} > {tabs?.length > 0 && tabs.map((tab, index) => { return ( - <> + {index === 0 ? : null} = (props) => { separatorComponent && separatorComponent(index)} - + ); })} {!hideSlider ? ( @@ -141,7 +169,7 @@ const TabBar: React.FC = (props) => { ); -}; +}); const styles = StyleSheet.create({ sliderContainer: { diff --git a/src/components/TabBar/type.ts b/src/components/TabBar/type.ts index 40e37ec..951c29c 100644 --- a/src/components/TabBar/type.ts +++ b/src/components/TabBar/type.ts @@ -1,4 +1,5 @@ import { DimensionValue, TextStyle, ViewStyle } from 'react-native'; +import { SharedValue } from 'react-native-reanimated'; export interface TabBarProps { tabs: Array; diff --git a/src/components/TabView/TabView.tsx b/src/components/TabView/TabView.tsx index 90d7067..0ff744b 100644 --- a/src/components/TabView/TabView.tsx +++ b/src/components/TabView/TabView.tsx @@ -1,7 +1,10 @@ -import React from 'react'; -import { View, Text } from 'react-native'; +import React, { useRef } from 'react'; +import { View, Text, Dimensions } from 'react-native'; import { TabBar } from '../TabBar'; -import { PageView } from '../PageView'; +import { PageView, PageViewRef } from '../PageView'; +import Animated, { useSharedValue } from 'react-native-reanimated'; + +const { width } = Dimensions.get('window'); interface TabViewProps {} @@ -9,11 +12,16 @@ const tabs = ['tab1', 'tab2', 'this is tab3', 'tab5', '11', 'tab8', 'ta11']; const TabView: React.FC = (props) => { const {} = props; + // const contentSize = width; + const currentIndex = useSharedValue(2); + const pageRef = useRef(null); + const tabRef = useRef(null); return ( - + ( @@ -26,18 +34,30 @@ const TabView: React.FC = (props) => { paddingVertical: 10, backgroundColor: 'orange', }} + onPress={(index) => { + // pageRef.current && pageRef.current?.setPage(index); + console.log('onPress index', index); + // currentIndex.value = index; + }} + initialTab={currentIndex.value} /> { // console.log('currentPage:', currentPage); + // tabRef.current && tabRef.current?.setTab(currentPage); }} onPageScrollStateChanged={(state) => { // console.log('state:', state); }} onPageScroll={(translate) => { // console.log('translate', translate); + // currentIndex.value = translate; + // const page = pageRef.current && pageRef.current?.getCurrentPage(); + // console.log('translate', page); + }} scrollEnabled={true} bounces={true} @@ -58,7 +78,7 @@ const TabView: React.FC = (props) => { ); })} - + ); };