如何使用react-navigation在堆栈/标签导航器之间实现共享的搜索栏输入?

时间:2020-05-08 01:11:15

标签: react-native react-navigation react-navigation-stack react-navigation-bottom-tab

Snapchat的用户界面当前使用浮动的SearchBar标头设置,该标头似乎在多个屏幕/选项卡之间共享。我想使用react-navigation复制共享的SearchBar标头。我目前有一半有效的解决方案...

Half working solution

当前,即使我在StackNavigator上设置了headerTitle,在导航到搜索结果屏幕时,标题似乎仍在渲染一个全新的SearchBar(您可以看到轻微的闪烁指示其渲染)。

这是我当前为TabNavigator中的一个堆栈设置。

function NetworkStack({ route, navigation }) {
    return (
        <Network.Navigator
            initialRouteName="NetworkEventList"
            screenOptions={({ navigation, route }) => ({
                headerTitle: () => <Search navigation={navigation} route={route} stackName={"NetworkStack"}/>,
            })}>
            <Network.Screen
                name="NetworkSearchResults"
                component={SearchResults}
                options={({ navigation, route }) => ({
                    //headerTitle: () => <Search navigation={navigation} route={route} focused={true} stackName={"NetworkStack"}/>,
                    headerBackImage: () => <BackButton navigation={navigation} shouldPop={true}/>,
                    headerBackTitleVisible: false,
                    gestureEnabled: true
                })}/>
            <Network.Screen
                name="NetworkEventList"
                component={NetworkEventList}
                options={({ navigation, route }) => ({
                    headerLeft: () => <ProfileSidebarButton navigation={navigation}/>,
                    //headerTitle: () => <Search navigation={navigation} focused={false} stackName={"NetworkStack"}/>,
                    headerRight: () => <CommunityButton navigation={navigation} stackName={"NetworkStack"}/>
                })}/>
        </Network.Navigator>
    )
}

下面是我的TabNavigator。

function TabNavigator({ navigation, route }) {
    return (
        <Tab.Navigator
            initialRouteName="NetworkStack"
            tabBar={props => <TabBar {...props}/>}>
            <Tab.Screen
                name="CheckInStack"
                component={CheckInStack}/>
            <Tab.Screen
                name="NetworkStack"
                component={NetworkStack}/>
            <Tab.Screen
                name="MapStack"
                component={MapStack}/>
        </Tab.Navigator>
    );
}

导航到搜索结果组件的逻辑在输入的onFocus侦听器内部。这是该代码...

const searchBarFocus = () => {
        switch(props.stackName) {
            case "MapStack":
                var searchType = props.searchGoogle ? "AddEstablishment" : "ViewingEstablishments";
                props.navigation.navigate('MapSearchResults', {searchType: searchType});
                break;
            case "NetworkStack":
                props.addingMarkers(false);
                var searchType = props.searchForPosting ? "ViewingEstablishments" : "ViewingUsers";
                let index = null;
                let routeState = props.route.state;
                if(routeState) index = routeState.index;
                if(index !== 1) {
                    console.log(props.navigation);
                    props.navigation.navigate('NetworkSearchResults', {searchType: searchType});
                }
                break;
            case "CheckInStack":
                props.addingMarkers(false);
                props.navigation.navigate('CheckInSearchResults', {searchType: "ViewingUsers"});
                break;
        }
    }

我该如何配置导航元素,以使我拥有一个可以装载一次的SearchBar元素?您可以在我上传的gif文件中看到,搜索栏也失去了对导航的关注,这也归因于我的Search组件的第二次渲染/安装。我们欢迎所有的建议!

1 个答案:

答案 0 :(得分:0)

我能够找到问题的解决方案。随时发表评论或提供更好的答案。我使用react-native-elements Search Bar在导航堆栈的标题处创建搜索/输入元素。最初,这是一个包装SearchBar组件的View。我将其更改为TouchableOpacity,以便可以监听onPress事件。这是我构造的新元素。我保留了问题中提供的原始导航配置。

return (
        <TouchableOpacity style={[styles.mainContainer, {width: SEARCH_BAR_WIDTH_UNFOCUSED}]} onPress={() => searchBarPress()}>
            <SearchBar
                id={"searchBar-"+ props.stackName}
                platform="ios"
                ref={search => searchRef = search}
                value={searchInput}
                containerStyle={styles.searchInputContainerWrapper}
                inputContainerStyle={styles.searchInputContainer}
                inputStyle={{color: styles.inputContainer.color}}
                round={true}
                autoFocus={props.route.params ? true : false}
                pointerEvents={props.route.params ? "auto" : "none"}
                cancelButtonTitle="Cancel"
                cancelButtonProps={{color: '#707070'}}
                onChangeText={updateSearch}
                //onFocus={searchBarFocus}
                onCancel={() => console.log("Cancel")}
            />
        </TouchableOpacity>
    )

创建Snapchat之类的关键部分(例如搜索栏标题)是autoFocus和pointerEvents属性。属性值必须取决于用户当前所在的屏幕。

enter image description here

相关问题