ReactNative搜索页面实现

本文详细介绍了使用ReactNative实现搜索页面的过程,包括组件初始化、获取搜索列表数据、处理关键字变化、保存搜索历史以及UI渲染等关键步骤。通过具体代码片段展示了如何在ReactNative中构建高效且用户体验良好的搜索功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ReactNative搜索页面实现


注意:具体 实现分析以及 效果图可以参考 简书链接

简书链接.

具体实现代码片

1、初始化.

export default class PostSearchView extends BaseComponent {
    constructor(props) {
        super(props);
        this.state = {
            value: '',
            placeholder: '搜索',
            isPostList: false, //是否搜索
            keyword: '',//搜索关键字
            searchHistory: [],// 搜索历史数组
            hotTagsArr: [],// 热门搜索标签数组
        };
    }
    componentDidMount() {
        this._getHotWords()
    }
    componentWillMount() {}

2、方法.

    //获取搜索列表数据
    _getHotWords() {
        ModalIndicator.show('请求中...')
        let params = '{"data":{}}'
        this._post('common/v2/campus/getHotWords', {},
            params, true, data => {
                ModalIndicator.hide()
                if (data.code == 0) {
                    console.log('hotTagsArr: ' + data.data)
                    console.log('hotTagsArr: ' + data.data.hot_words)
                    if (!_.isEmpty(data.data.hot_words)) {
                        this.setState({
                            hotTagsArr: data.data.hot_words,
                        })
                    } else {
                        this.setState({
                            hotTagsArr: [],
                        })
                    }
                } else {
                    _showModalMessage(this.props.navigation, data.msg);
                }
            }, err => {
                ModalIndicator.hide()
                console.log('err: ', err)
            })
    }
    
    //关键字改变
    onChanegeTextKeyword(Val) {
        let keys = {};
        //输入的关键字去空格空字符
        let newVal = Val.replace(/(^\s*)|(\s*$)/g, "")
        if (!_.isEmpty(newVal)) {
            keys = {
                keyword: newVal
            };
            this.setState({isPostList: true})
        } else {
            Toast.message('请输入搜索关键字', null, 'center')
        }
        this.setState({keyword: keys});
    }

    //历史和热门标签值赋值输入框
    _setValues(item) {
        this.setState({value: item})
    }

    //聚焦
    _onFous(v) {
        if (v.nativeEvent.target) {
            this.setState({isPostList: false})
        }
    }

    //删除历史搜索数据
    _deleteHistory() {
        // 判断是否有本地搜索历史
        if (this.state.searchHistory.length > 0) {
            Alert.alert(
                '提示',
                '确定清除所有历史搜索记录吗?',
                [
                    {text: '取消', onPress: () => console.log('取消'), style: 'cancel'},
                    {
                        text: '确定', onPress: () => {
                            Toast.message('清除历史搜索记录成功', null, 'center')
                            removeItem("searchHistory");
                            this.setState({
                                value: '',
                                searchHistory: [],
                            })
                        }
                    },
                ]
            )
        }
    }

    //获取历史记录
    _getHistory() {
        // 查询本地历史
        getItems("searchHistory").then(data => {
            if (data == null) {
                this.setState({
                    searchHistory: [],
                })
            } else {
                this.setState({
                    searchHistory: data,
                })
            }
        })
    }

    // 保存搜索标签
    _insertSearch(newText) {
        let text = newText.replace(/(^\s*)|(\s*$)/g, "")
        if (!_.isEmpty(text)) {
            if (this.state.searchHistory.indexOf(text) != -1) {
                // 本地历史 已有 搜索内容
                let index = this.state.searchHistory.indexOf(text);
                let tempArr = arrDelete(this.state.searchHistory, index)
                tempArr.unshift(text);
                setItem("searchHistory", tempArr);
            } else {
                // 本地历史 无 搜索内容
                let tempArr = this.state.searchHistory;
                tempArr.unshift(text);
                setItem("searchHistory", tempArr);
            }
        }
    }

3、UI渲染.

render() {
        return (
            <View style={styles.container}>
                {/*监听页面,刷新搜索本地历史历史*/}
                <NavigationEvents onWillFocus={() => {
                    //查询本地搜索历史
                    this._getHistory();
                }}/>
                <Header title='搜索'
                        navigation={this.props.navigation}
                        show_close_img={true}
                />
                <View style={styles.inputBox}>
                    <View style={styles.inputIcon}>
                        <Image source={require('../../imgs/public_icon_search.png')}/>
                    </View>
                    <TextInput style={styles.inputText}
                               autoCapitalize="none"
                               value={this.state.value}
                               onChangeText={(text) => this.setState({value: text})}
                               onSubmitEditing={() => {
                                   //开始搜索
                                   this.onChanegeTextKeyword(this.state.value);
                                   // 保存搜索内容
                                   this._insertSearch(this.state.value);
                               }}
                               returnKeyType="search"
                               underlineColorAndroid="transparent"
                               placeholder={this.state.placeholder}
                               placeholderTextColor={'#BFBFBF'}
                               onFocus={this._onFous.bind(this)}
                               autoFocus={true}
                               defaultValue={this.state.value}
                               keyboardType="default"/>
                </View>
                <View style={styles.lin}/>
                {
                    (this.state.isPostList) ?
                        //列表
                        <ScrollView style={styles.scrollView}>
                            <View style={styles.listView}>
                                <PostSearchList keyword={this.state.keyword}{...this.props}/>
                            </View>
                        </ScrollView>
                        :
                        //历史和热门
                        <ScrollView style={styles.scrollView}>
                            <View style={styles.head1}>
                                <Text style={{fontSize: scale(14), color: "#333"}}>{"历史搜索"}</Text>
                                <TouchableOpacity activeOpacity={0.3} onPress={() => this._deleteHistory()}>
                                    <Image source={require('../../imgs/public_icon_del.png')}/>
                                </TouchableOpacity>
                            </View>
                            {
                                this.state.searchHistory.length > 0 ?
                                    <View style={styles.queryList}>
                                        {this.state.searchHistory.map((item, index) => {
                                            return (
                                                <View key={index}>
                                                    <TouchableOpacity onPress={() => {
                                                        //去搜索
                                                        this.onChanegeTextKeyword(item);
                                                        //给输入框赋值
                                                        this._setValues(item);
                                                        // 保存搜索内容
                                                        this._insertSearch(item);
                                                    }} activeOpacity={0.3}>
                                                        <Text numberOfLines={1} style={styles.queryItem}>{item}</Text>
                                                    </TouchableOpacity>
                                                </View>
                                            )
                                        })}
                                    </View>
                                    :
                                    <View style={styles.noData}>
                                        <Text style={styles.noDataTxt}>暂无搜索历史</Text>
                                    </View>
                            }
                            <View style={styles.head}>
                                <Text style={{fontSize: scale(14), color: "#333"}}>{"热门搜索"}</Text>
                            </View>
                            {
                                this.state.hotTagsArr.length > 0 ?
                                    <View style={styles.queryList}>
                                        {/* 热门搜索标签渲染 */}
                                        {this.state.hotTagsArr.map((item, index) => {
                                            return (
                                                <View key={index}>
                                                    <TouchableOpacity onPress={() => {
                                                        //去搜索
                                                        this.onChanegeTextKeyword(item);
                                                        //给输入框赋值
                                                        this._setValues(item);
                                                        // 保存搜索内容
                                                        this._insertSearch(item);
                                                    }} activeOpacity={0.3}>
                                                        <Text numberOfLines={1} style={styles.queryItem}>{item}</Text>
                                                    </TouchableOpacity>
                                                </View>
                                            )
                                        })}
                                    </View>
                                    :
                                    <View style={styles.noData}>
                                        <Text style={styles.noDataTxt}>更多热词敬请期待</Text>
                                    </View>
                            }

                        </ScrollView>
                }
            </View>
        )
    }
}

3、样式style.

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
    },
    inputBox: {
        height: Platform.OS === 'ios' ? 25 : 35,
        marginLeft: 15,
        marginRight: 15,
        flexDirection: 'row',
        backgroundColor: '#F4F4F4',
        borderRadius: 8,
        borderWidth: 0,
        marginTop: 10,
    },
    lin: {
        height: 1,
        marginLeft: 5,
        marginRight: 5,
        backgroundColor: '#f1f1f1',
        marginTop: 10,
    },
    scrollView: {},
    listView: {
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'center',
        marginLeft: 0,
        marginRight: 0,
        marginTop: 10,
    },
    head1: {
        paddingHorizontal: 16,
        marginTop: 18,
        flexDirection: "row",
        alignItems: "center",
        justifyContent: "space-between"
    },
    head: {
        paddingHorizontal: 16,
        marginTop: 8,
        flexDirection: "row",
        alignItems: "center",
        justifyContent: "space-between"
    },
    queryList: {
        marginTop: 10,
        marginRight: 16,
        marginLeft: 16,
        flexDirection: "row",
        flexWrap: "wrap",
        alignItems: "center",
        backgroundColor: "#fff"
    },
    queryItem: {
        flex: 1,
        fontSize: scale(12),
        backgroundColor: '#F4F4F4',
        paddingHorizontal: 30,
        paddingVertical: 6,
        borderRadius: 3,
        marginRight: 10,
        marginBottom: 10
    },
    inputIcon: {
        margin: Platform.OS === 'ios'
            ? 5
            : 10
    },
    inputText: {
        flex: 1,
        paddingLeft: 5,
        textAlignVertical: 'center',
        paddingVertical: 0
    },
    noData: {
        flexDirection: "row",
        justifyContent: "center",
        alignItems: "center",
        backgroundColor: "#fff",
        marginTop: 10,
        marginBottom: 12,
    },
    noDataTxt: {
        fontSize: scale(12),
    },
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值