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

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

功能

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

React-Native 城市列表(仿美团)_第1张图片
导航跳转.gif

提供搜索功能

React-Native 城市列表(仿美团)_第2张图片
搜索功能.gif

说明

简单介绍

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

                  this._getItemLayout(data,index)}
                        keyExtractor={(item,index)=>{
                            return(index.toString());
                        }}
                   >
                    

这样看很简单吧。
数据的初始化是在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( 
                    
                        {txt}
                    
                )
            }
            case 'letter':{
                return(
                    
                        {txt}
                    
                )
            }
            case 'desc':{
                return(
                    
                        {txt}
                    
                )
            }
            case 'city2':{
                txt = txt.split(',');
                return(
                    
                        {
                            txt.map((element,index) => {
                                return 
                                    {element}
                                
                            })
                        }
                    
                    )
            }
            case 'location':{
                return(
                    
                        {txt}
                    
                )
            }
        }
    }

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

你可能感兴趣的:(React-Native 城市列表(仿美团))