React-Native 城市列表(仿美团)

作者: 易之108 | 来源:发表于2018-07-25 13:56 被阅读46次

    项目需要写了一个城市列表的界面,供有需要的人参考一下

    功能

    点击右侧导航滚动到响应位置

    导航跳转.gif

    提供搜索功能

    搜索功能.gif

    说明

    简单介绍

    我使用的FlatList。一开始也尝试使用SectionList,但是在尝试执行跳转时发现位置不好计算,而且感觉SectionList的效率并不如FlatList 所以就使用FlatList 了。

                      <FlatList 
                            ref = {'FlatList'}
                            style={{width:'100%'}}
                            data={this.state.sections}
                            contentContainerStyle = {styles.list}
                            showsVerticalScrollIndicator = {false}
                            renderItem = {this._renderItem}
                            initialNumToRender = {50}
                            getItemLayout={(data, index) =>this._getItemLayout(data,index)}
                            keyExtractor={(item,index)=>{
                                return(index.toString());
                            }}
                       >
                       </FlatList> 
    

    这样看很简单吧。
    数据的初始化是在componentDidMount 中完成的
    数据来源是从其他人的代码中找到的json文件。
    另外因为要加入,定位城市,常用城市,热门城市,所以变成了下面的样子。

    componentDidMount(){
            let cityContent2 = cityContent.data;
            let letterList = [];              // 侧边的导航数据
            let cityArray = [];
            let sections = [];              // 最后将所以的信息放入其中
            this.city2number = 0;
            this.descNumber = 0;
            this.titleCityArray = [0];
    
            sections[sections.length] = {
                name:'定位城市',
                type:'desc',
            };
    
            sections[sections.length] = {
                name:'珠海',
                type:'location',
            };
            sections[sections.length] = {
                name:'常用城市',
                type:'desc',
            };
            //在定位城市和热门城市中设置 三个城市是一个组。
            // 不然不好实现将他们放在一行中的操作。使用flexWrap 也能实现,但是会导致计算起来麻烦
           //设置不同的type 在 FlatList 中的 renderItem 中用于区分,实现不同的样式
            sections[sections.length] = {
                name:'珠海,广州',
                type:'city2',
            };
    
            sections[sections.length] = {
                name:'热门城市',
                type:'desc',
            };
    
            sections[sections.length] = {
                name:'珠海,广州,杭州',
                type:'city2',
            };
            sections[sections.length] = {
                name:'北京,上海,西安',
                type:'city2',
            };
            sections[sections.length] = {
                name:'广州,杭州,北京',
                type:'city2',
            };
            sections[sections.length] = {
                name:'上海,西安',
                type:'city2',
            };
            letterList.splice(0,0,'定位','常用','热门');
           
          
            sections.forEach(element => {
                if(element.type != 'desc'){
                    this.city2number++;
                }else{
                    this.descNumber++;
                }
            });
            let i = 0;
            cityContent2.forEach(element => {
                sections[sections.length] = {
                    name:element.title,
                    type:'letter',
                };
                element.city.forEach(element => {
                    if(element.city_child == element.city_parent){
                        sections[sections.length] = {
                            name:element.city_child,
                            type:'city',
                        }
                        i++;
                    }
                });
                this.titleCityArray[this.titleCityArray.length] = i;
                letterList[letterList.length] = element.title;
            });
            
            
    
    
         // 查找时使用的数据
            let key = 0;
            cityArray = [];
            cityContent2.forEach(element => {
                element.city.forEach(element => {
                    if(element.city_child == element.city_parent){
                    cityArray[cityArray.length] = {
                        'name':element.city_child,
                        'name_en':element.city_child_en,
                        'key':key++,
                    }
                    }
                });
            });
            this.setState({
              sections:sections,
              listData:letterList,
              cityBase:cityArray,
              searchArray:cityArray,
            });
        
        }
    

    下面是_renderItem 根据不同的type 返回不同的样式。

    _renderItem = (info) => {
            var txt = '  ' + info.item.name;
            switch(info.item.type){
                case 'city':{
                    return( 
                        <Text
                            style={{ 
                                height: CITYHEIGHT,
                                width:Utils.size.width-70,
                                textAlignVertical: 'center', 
                               // backgroundColor: "#ffffff", 
                                color: '#5C5C5C', 
                                fontSize: 15,
                                borderBottomColor:'rgb(161,161,161)',
                                borderBottomWidth:1, 
                                }}
                            >
                            {txt}
                        </Text>
                    )
                }
                case 'letter':{
                    return(
                        <Text
                            style={{ 
                                height: TITLEHEIGHT,
                                width:Utils.size.width-70,
                                textAlignVertical: 'center', 
                                //backgroundColor: "#0f0", 
                                color: '#5C5C5C', 
                                fontSize: 15,
                                borderBottomColor:'rgb(161,161,161)',
                                borderBottomWidth:1, 
                                }}
                            >
                            {txt}
                        </Text>
                    )
                }
                case 'desc':{
                    return(
                        <Text
                            style={{ 
                                height: DESCHEIGHT,
                                width:Utils.size.width-50,
                                textAlignVertical: 'center', 
                                //backgroundColor: "#0f0", 
                                color: '#5C5C5C', 
                                fontSize: 15,
                                }}
                            >
                            {txt}
                        </Text>
                    )
                }
                case 'city2':{
                    txt = txt.split(',');
                    return(
                        <View style={{
                            flexDirection:'row',
                        }}>
                            {
                                txt.map((element,index) => {
                                    return <Text
                                        key={'info'+info.index+'index'+index}
                                        style={{ 
                                        textAlignVertical: 'center', 
                                        textAlign:'center',
                                        width:94.5,
                                        height:CITYHEIGHT2,
                                        borderColor:'rgb(220,220,220)',
                                        borderWidth:Utils.pixel,
                                        fontSize: 15 ,
                                        marginRight:14,
                                    }}>
                                        {element}
                                    </Text>
                                })
                            }
                        </View>
                        )
                }
                case 'location':{
                    return(
                        <Text
                            style={{ 
                            textAlignVertical: 'center', 
                            textAlign:'center',
                            width:94.5,
                            height:CITYHEIGHT2,
                            borderColor:'rgb(220,220,220)',
                            borderWidth:Utils.pixel,
                            fontSize: 15 ,
                            marginRight:14,
                            //marginTop:4
                        }}>
                            {txt}
                        </Text>
                    )
                }
            }
        }
    

    这样大体就完成了。
    码云 中有全部的代码。欢迎下载。
    https://gitee.com/yizhi108/react-native-location/
    如有其它问题,欢迎留言讨论。

    相关文章

      网友评论

      • haisonLIN:你好,想问下大佬获取网络图片,宽度是屏幕宽,怎么让高度等比例设置

        // 网络图片,通过URL获取宽高
        imageSize(url){
        Image.getSize(url,
        (width,height)=>{
        return {'width':width,'heigth':height}
        },
        (error)=>{
        console.warn(error);
        })
        }

      本文标题:React-Native 城市列表(仿美团)

      本文链接:https://www.haomeiwen.com/subject/ccwuuftx.html