создать настраиваемую прокручиваемую верхнюю панель вкладок с помощью response-navigation-tab? - PullRequest
0 голосов
/ 20 июня 2020

Мне нужно создать настраиваемую прокручиваемую верхнюю панель вкладок с использованием вкладок навигации и tabBarComponent без использования какой-либо другой сторонней библиотеки.

const TopTabBar = createMaterialTopTabNavigator({
    Home: HomePage,
    Entertainment: EntertainmentNews,
    Business: BusinessStack,
    Music: MusicStack,
    Politics: PoliticsStack,
    Sports: SportsStack,
    Technology: TechnologyStack,
    WorldNews: WorldNewsStack
}, {
    tabBarComponent: (props) => <TopTabBarComponent {...props}/>
})

В этом компоненте панели вкладок я могу создать верхнюю панель а он не прокручивается при смахивании экрана?

import React , { Component } from 'react'
import { Text, View, StyleSheet, FlatList, TouchableOpacity, Animated, Dimensions} from 'react-native'

interface Props {
    navigation?: any
}

interface State {
    //
}

export class TopTabBarComponent extends Component <Props, State>{
    flatListRef
    constructor(props: Props, state: State){
        super(props, state)
    }





    onPressItem = (index) => {
        const { navigation } = this.props
        navigation.navigate( this.props.navigation.state.routes[index].routeName )
        // this.onScrollIndex(index)
    }

    renderTopBar = (item, index) => {
        const routes = this.props.navigation.state.routes
        const activeIndex = this.props.navigation.state.index

            return (
                <TouchableOpacity style = {{
                     alignItems: 'center' ,  
                     height: 50, 
                     justifyContent: 'center', 
                     borderBottomWidth: activeIndex === index ?  2 : 0, 
                     borderColor: 'green', 
                     paddingHorizontal: 5
                     }} onPress = {() => this.onPressItem(index)}>  
                    <Text style = {{ fontSize: 20, color: 'blue'}}>{item.routeName}</Text>
                </TouchableOpacity>
            )
    }

    render() {
        // reactotron.log('this.props', this.props.navigation)
        console.warn('this.props.navigation.state.index', this.props.navigation.state.index)
        return(
            <View style = {{ marginHorizontal: 5}}>
                <FlatList
                    initialScrollIndex = { this.props.navigation.state.index }
                    ref = {(ref) => { this.flatListRef = ref}}
                    // style = {{ paddingHorizontal: 20}}
                    horizontal
                    showsHorizontalScrollIndicator = {false}
                    data = {this.props.navigation.state.routes}
                    renderItem = {({item , index}) => this.renderTopBar(item, index) }
                    ItemSeparatorComponent = {() => <View style = {{ paddingRight: 40}}/>}
                    />
            </View>
        )
    }

}

Это код компонента штрих-кода верхней вкладки? Итак, как я могу сделать так, чтобы верхняя вкладка прокручивалась автоматически при смахивании экранов?

1 Ответ

0 голосов
/ 20 июня 2020

Это образец моей панели вкладок, который я быстро отредактировал для вашего тестового примера.

function MyTabBar({ state, descriptors, navigation, position }) {
    const scrollViewRef = useRef(null)

    useEffect(() => {
        scrollViewRef.current.scrollTo({ x: state.index * 50, y: 0, animated: true })
    }, [state.index])

    return (
        <View style={styles.tabContainer}>
            <ScrollView ref={list => scrollViewRef.current = list} contentContainerStyle={{ flexDirection: 'row', alignItems: 'center'}} horizontal>
                {state.routes.map((route, index) => {
                    const { options } = descriptors[route.key];
                    const label =
                        options.tabBarLabel !== undefined
                        ? options.tabBarLabel
                        : options.title !== undefined
                        ? options.title
                        : route.name;

                    const isFocused = state.index === index;
                    const onPress = () => {
                        const event = navigation.emit({
                        type: 'tabPress',
                        target: route.key,
                        });

                        if (!isFocused && !event.defaultPrevented) {
                        navigation.navigate(route.name);
                        }
                    };

                    const onLongPress = () => {
                        navigation.emit({
                        type: 'tabLongPress',
                        target: route.key,
                        });
                    };

                    let focusStyle = { }; //style object to append to the focussed tab
                    let tintColor = { };
                    let fontColor = { };
                    isFocused ? focusStyle = { backgroundColor: 'darkgray' } : focusStyle = { };
                    isFocused ? tintColor = { tintColor: 'black' } : tintColor = { tintColor: 'lightgray' }; // TODO: change this with proper fontColor codes
                    isFocused ? fontColor = { color: 'black' } : fontColor = { color: 'lightgray' };
                    //below controls the rendered tab

                        return (
                            <TouchableWithoutFeedback
                                key={index}
                                onPress={onPress}
                                onLongPress={onLongPress}
                                style={[styles.tabItem, focusStyle]}
                            >
                                    <View style={styles.tabIconContainer}>
                                        <LearnTabIcon title={route.name} color={tintColor} />
                                    </View>
                                    <Text style={[styles.labelStyle, fontColor]}>
                                        {label}
                                    </Text>
                            </TouchableWithoutFeedback>
                        );
                })}
            </ScrollView>

            <View style={styles.tabBarIndicator}>
                { state.routes.map((route, index) => {
                    const isFocused = state.index === index;
                    let selectedStyle = { };
                    isFocused ? selectedStyle = { backgroundColor: 'darkgray'} : { }; // TODO: change this coloring to actual color codes
                    return (
                        <View 
                            style={[styles.tabIndicators, selectedStyle]}
                            key={index}
                        >
                        </View>
                    );
                })}
            </View>
        </View>
    );
  }

Я использую функциональные компоненты для всего, поэтому он будет выглядеть немного иначе, но на вашей настраиваемой панели вкладок возьмите state.index при каждом изменении индекса, а затем используйте scrollToOffset, чтобы контролировать, где прокрутка будет центрирована на экране. Я добавил образец шкалы смещения в 50 пикселей для простоты.

Я тоже не использовал TypeScript, но у вас, похоже, большая часть котельной плиты уже готова к go.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...