项目需要写了一个城市列表的界面,供有需要的人参考一下
功能
点击右侧导航滚动到响应位置
提供搜索功能
说明
简单介绍
我使用的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/
如有其它问题,欢迎留言讨论。