1- import React from 'react' ;
1+ import React , { useRef , useEffect , useState } from 'react' ;
22import { StyleSheet , SafeAreaView , StatusBar , ScrollView , ViewProps , View , ViewStyle , Dimensions } from 'react-native' ;
33
44import Item from './TabsItem' ;
55
6- let MainWidth = Dimensions . get ( 'window' ) . width ;
7-
86export interface TabsProps extends ViewProps {
97 /** 子元素 */
108 children ?: JSX . Element | Array < JSX . Element > ;
@@ -18,9 +16,24 @@ export interface TabsProps extends ViewProps {
1816
1917function Tabs ( props : TabsProps ) {
2018 const { style, children, onChange, activeColor, value, defaultColor = '#035bb6' } = props ;
19+ const scrollViewRef = useRef < ScrollView > ( null ) ;
20+ const [ scrollViewWidth , setScrollViewWidth ] = useState < number > ( Dimensions . get ( 'window' ) . width ) ;
21+
22+ useEffect ( ( ) => {
23+ const handleResize = ( ) => {
24+ setScrollViewWidth ( Dimensions . get ( 'window' ) . width ) ;
25+ } ;
26+ Dimensions . addEventListener ( 'change' , handleResize ) ;
27+
28+ return ( ) => {
29+ Dimensions . removeEventListener ( 'change' , handleResize ) ;
30+ } ;
31+ } , [ ] ) ;
32+
2133 if ( ! children ) {
2234 return null ;
2335 }
36+
2437 if (
2538 Array . isArray ( children ) &&
2639 children . find ( ( item ) => typeof item . type !== 'function' || ! item . type . prototype . isclxItem )
@@ -36,10 +49,30 @@ function Tabs(props: TabsProps) {
3649 throw new Error ( 'Child elements of tabs components must be Tabs.Item' ) ;
3750 }
3851
52+ const handleTabChange = ( tabIndex : number ) => {
53+ scrollViewRef . current ?. scrollTo ( {
54+ x : tabIndex * 50 ,
55+ y : 0 ,
56+ animated : true ,
57+ } ) ;
58+ onChange && onChange ( tabIndex ) ;
59+ } ;
60+
3961 return (
4062 < SafeAreaView >
4163 < View style = { [ styles . TabsContainer , style ] } >
42- < ScrollView horizontal showsHorizontalScrollIndicator = { false } >
64+ < ScrollView
65+ ref = { scrollViewRef }
66+ horizontal
67+ showsHorizontalScrollIndicator = { false }
68+ contentContainerStyle = { {
69+ justifyContent : 'space-between' ,
70+ alignItems : 'center' ,
71+ } }
72+ onContentSizeChange = { ( ) => {
73+ setScrollViewWidth ( Dimensions . get ( 'window' ) . width ) ;
74+ } }
75+ >
4376 { children &&
4477 React . Children . toArray ( children ) . map ( ( child , index ) => {
4578 if ( ! React . isValidElement ( child ) ) {
@@ -49,7 +82,7 @@ function Tabs(props: TabsProps) {
4982 ...child . props ,
5083 ...{
5184 value : value ,
52- onChange : onChange ,
85+ onChange : handleTabChange ,
5386 index : index ,
5487 activeColor : activeColor ,
5588 defaultColor : defaultColor ,
@@ -74,10 +107,6 @@ function Tabs(props: TabsProps) {
74107const styles = StyleSheet . create ( {
75108 TabsContainer : {
76109 backgroundColor : '#fff' ,
77- maxWidth : 1 * MainWidth ,
78- display : 'flex' ,
79- justifyContent : 'space-between' ,
80- alignItems : 'center' ,
81110 paddingVertical : 15 ,
82111 } ,
83112} ) ;
0 commit comments