【问题标题】:How to implement a shared Search Bar input across stack/tab navigators using react-navigation?如何使用 react-navigation 跨堆栈/选项卡导航器实现共享搜索栏输入?
【发布时间】:2020-08-23 11:48:05
【问题描述】:

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

目前,即使我在 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 中看到搜索栏也失去了对导航的关注,这也是由于我的搜索组件的第二次渲染/安装。我们欢迎所有的建议!

【问题讨论】:

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


    【解决方案1】:

    我能够找到我的问题的解决方案。随意评论或提供更好的答案。我使用react-native-elements Search Bar 在导航堆栈的标题处创建我的搜索/输入元素。最初这是一个包装 SearchBar 组件的视图。我将其更改为 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 属性。属性值需要取决于用户当前在哪个屏幕上。

    【讨论】:

    • 嗨,我正在尝试做同样的事情,但我没有将搜索栏放在标题中,而是将其作为屏幕中的一个组件返回。有没有可能帮到我?
    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2020-03-30
    • 1970-01-01
    • 2019-08-28
    • 2020-07-14
    • 2019-07-04
    • 1970-01-01
    相关资源
    最近更新 更多