效果图:
主逻辑文件 cityList.js
import React, { Component } from "react"
import { Dimensions, ScrollView, StyleSheet, Text, TouchableOpacity, View ,PixelRatio} from 'react-native';
import cityDatas from "./city";
const { width, height } = Dimensions.get('window');
// 适配性函数
const UIWIDTH = 750;
let hotCitys = [];
let defaultHotCityArray = [
{ cityCode: "310000", cityName: "上海市" },
{ cityCode: "440300", cityName: "深圳市" },
{ cityCode: "110000", cityName: "北京市" },
{ cityCode: "440100", cityName: "广州市" },
];
const sectionWidth = 20;
const statusHeight = 88;
const sectionTopBottomHeight = 60;
const sectionItemHeight = (height - sectionTopBottomHeight * 2 - statusHeight) / cityDatas.length;
const ROW_HEIGHT = 48;
let totalHeight = [];
let letters = [];
export function rx(UIPX) {
return Math.round(UIPX * width / UIWIDTH);
}
export default class cityList extends Component {
constructor(props) {
super(props);
totalHeight = this._gotTotalHeightArray();
letters = this._gotLettersArray();
}
state = {
currentCity: "正在定位...",
isLocation: false,
sectionListDatas: cityDatas,
letterWords: 'A'
};
// 获取每个字母区域的高度
_gotTotalHeightArray() {
let totalArray = []
for (let i = 0; i < cityDatas.length; i++) {
let eachHeight = ROW_HEIGHT * (cityDatas[i].data.length + 1);
totalArray.push(eachHeight);
}
return totalArray
}
// 获取字母列表头
_gotLettersArray() {
let LettersArray = []
for (let i = 0; i < cityDatas.length; i++) {
let element = cityDatas[i];
LettersArray.push(element.title)
}
return LettersArray
}
componentWillMount() {
this.gotCurrentLocation();
this.requestHotCityList();
}
async gotCurrentLocation() {
this.setState({
currentCity: "北京",
isLocation: true
})
}
requestHotCityList() {
hotCitys = defaultHotCityArray
}
currentCityAction(name) {
}
// 点击右侧字母滑动到相应位置
scrollToList(item, index) {
let position = 0;
for (let i = 0; i < index; i++) {
position += totalHeight[i]
}
this.refs.ScrollView.scrollTo({ y: position })
}
/*右侧索引*/
_renderSideSectionView() {
const sectionItem = cityDatas.map((item, index) => {
return (
<Text onPress={() => this.scrollToList(item, index)} key={index} style={styles.rightSideText}>
{item.sortLetters}
</Text>
)
});
return (
<View
onMoveShouldSetResponder={() => true}
onResponderReject={(e) => { console.log("err:" + e) }}
onResponderGrant={e => {
console.log("success:" + e)
}}
onResponderMove={e => {
this.ontachMove(sectionItem,e.nativeEvent.locationY)
console.log(`move:X=>${e.nativeEvent.locationX}; Y=>${e.nativeEvent.locationY}; pageY=>${e.nativeEvent.pageY}`)
}
}
style={styles.rightSlideArea}
pointerEvents="box-only"
ref="sectionItemView">
{sectionItem}
</View>
);
}
// 滑动事件
ontachMove(section,pageY){
let pY = pageY / PixelRatio.get();
// console.log(PixelRatio.get() + "::::"+pY)
let index = parseInt( pY / sectionItemHeight);
console.log("index:"+index);
let item = section[index]
this.scrollToList(item, index)
}
// 渲染城市列表
_renderCityList() {
let lists = [];
for (let i = 0; i < cityDatas.length; i++) {
let sections = cityDatas[i];
let header =
<View key={sections.title} style={styles.cityLetterBox}>
<Text style={styles.cityLetterText}>{sections.sortLetters}</Text>
</View>;
lists.push(header);
for (let j = 0; j < sections.data.length; j++) {
let element = sections.data[j];
let cityCell =
<TouchableOpacity key={element.name + j} onPress={() => {
this.selectCity(element)
}}>
<View style={styles.cityTextBox}>
<Text style={styles.cityTextStyle}>{element.name}</Text>
</View>
</TouchableOpacity>;
lists.push(cityCell);
}
}
return lists;
}
selectCity(cityItem) {
// alert(cityItem.cityCode);
console.log(cityItem)
}
renderHotCityArray(hotCityArray) {
let eleArray = [];
let subArray = hotCityArray.slice(0, 12);
for (let index = 0; index < subArray.length; index++) {
const element = subArray[index];
const ele =
<TouchableOpacity key={element.cityCode} onPress={() => {
}}>
<View style={[styles.textView, { marginTop: 10 }]}>
<Text style={{ color: "#333333", fontSize: 14, }}>{element.cityName}</Text>
</View>
</TouchableOpacity>;
eleArray.push(ele);
}
return eleArray;
}
render() {
return (
<View style={{ flex: 1 }}>
<View style={{ backgroundColor: "#FFFFFF", }} ref='topViews'>
<Text style={styles.titleText}>当前定位城市</Text>
<View style={styles.currentView}>
<TouchableOpacity onPress={() => {
this.currentCityAction(this.state.currentCity)
}}
style={{ width: 100, }}>
<View style={[styles.textView, { marginLeft: 15, width: 100, }]}>
<Text style={{ color: "#C49225", fontSize: 14, }}>{this.state.currentCity}</Text>
</View>
</TouchableOpacity>
</View>
<Text style={styles.titleText}>热门城市</Text>
<View style={styles.hotView}>
{this.renderHotCityArray(hotCitys)}
</View>
</View>
<ScrollView style={{ backgroundColor: '#FFFFFF', }} ref="ScrollView">
{this._renderCityList()}
</ScrollView>
{this._renderSideSectionView()}
</View>
)
}
}
const styles = StyleSheet.create({
scrollView: {
backgroundColor: "#ECEBED"
},
titleText: {
marginLeft: 30,
marginTop: 20,
color: "#999999",
fontSize: 13,
},
currentView: {
marginTop: 10,
paddingBottom: 20
},
textView: {
minWidth: 40,
height: 30,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#FFF",
borderRadius: 5,
paddingLeft: 10,
paddingRight: 10,
marginRight: 10,
},
hotView: {
marginTop: 5,
flexDirection: "row",
flexWrap: "wrap",
justifyContent: "space-between",
marginLeft: 30,
marginRight: 25,
paddingBottom: 20,
marginBottom: 15,
},
rightSlideArea: {
position: 'absolute',
width: sectionWidth,
height: height - sectionTopBottomHeight * 2, right: 5,
top: 0,
marginTop: sectionTopBottomHeight,
marginBottom: sectionTopBottomHeight,
},
rightSideText: {
textAlign: 'center',
alignItems: 'center',
height: sectionItemHeight,
lineHeight: sectionItemHeight,
color: '#C49225'
},
cityLetterBox: {
height: ROW_HEIGHT,
backgroundColor: '#F4F4F4',
justifyContent: 'center',
},
cityLetterText: {
color: "#999",
fontSize: 17,
marginLeft: 20,
},
cityTextBox: {
height: ROW_HEIGHT,
justifyContent: 'center',
backgroundColor: '#FFFFFF',
marginLeft: 20,
},
cityTextStyle: {
color: '#333333',
fontSize: 14,
},
});
数据文件: city.js
export default [{"sortLetters":"A","data":[{"id":"152900","name":"阿拉善盟"},{"id":"210300","name":"鞍山"},{"id":"340800","name":"安庆"},{"id":"410500","name":"安阳"},{"id":"513200","name":"阿坝藏族羌族自治州"},{"id":"520400","name":"安顺"},{"id":"542500","name":"阿里地区"},{"id":"610900","name":"安康"},{"id":"659002","name":"阿拉尔"},{"id":"652900","name":"阿克苏地区"},{"id":"654300","name":"阿勒泰地区"}]},{"sortLetters":"B","data":[{"id":"110100","name":"北京"},{"id":"130600","name":"保定"},{"id":"150200","name":"包头"},{"id":"150800","name":"巴彦淖尔"},{"id":"210500","name":"本溪"},{"id":"220600","name":"白山"},{"id":"220800","name":"白城"},{"id":"340300","name":"蚌埠"},{"id":"341600","name":"亳州"},{"id":"371600","name":"滨州"},{"id":"450500","name":"北海"},{"id":"451000","name":"百色"},{"id":"469025","name":"白沙黎族自治县"},{"id":"469029","name":"保亭黎族苗族自治县"},{"id":"511900","name":"巴中"},{"id":"520500","name":"毕节"},{"id":"530500","name":"保山"},{"id":"610300","name":"宝鸡"},{"id":"620400","name":"白银"},{"id":"659005","name":"北屯"},{"id":"652700","name":"博尔塔拉蒙古自治州"},{"id":"652800","name":"巴音郭楞蒙古自治州"}]},{"sortLetters":"C","data":[{"id":"130800","name":"承德"},{"id":"130900","name":"沧州"},{"id":"140400","name":"长治"},{"id":"150400","name":"赤峰"},{"id":"220100","name":"长春"},{"id":"320400","name":"常州"},{"id":"341100","name":"滁州"},{"id":"341700","name":"池州"},{"id":"430100","name":"长沙"},{"id":"430700","name":"常德"},{"id":"431000","name":"郴州"},{"id":"445100","name":"潮州"},{"id":"451400","name":"崇左"},{"id":"469026","name":"昌江黎族自治县"},{"id":"469023","name":"澄迈县"},{"id":"510100","name":"成都"},{"id":"532300","name":"楚雄彝族自治州"},{"id":"540300","name":"昌都"},{"id":"652300","name":"昌吉回族自治州"}]},{"sortLetters":"D","data":[{"id":"140200","name":"大同"},{"id":"210200","name":"大连"},{"id":"210600","name":"丹东"},{"id":"230600","name":"大庆"},{"id":"232700","name":"大兴安岭地区"},{"id":"370500","name":"东营"},{"id":"371400","name":"德州"},{"id":"441900","name":"东莞"},{"id":"442100","name":"东沙群岛"},{"id":"460400","name":"儋州"},{"id":"469021","name":"定安县"},{"id":"469007","name":"东方"},{"id":"510600","name":"德阳"},{"id":"511700","name":"达州"},{"id":"532900","name":"大理白族自治州"},{"id":"533100","name":"德宏傣族景颇族自治州"},{"id":"533400","name":"迪庆藏族自治州"},{"id":"621100","name":"定西"}]},{"sortLetters":"E","data":[{"id":"150600","name":"鄂尔多斯"},{"id":"420700","name":"鄂州"},{"id":"422800","name":"恩施土家族苗族自治州"}]},{"sortLetters":"F","data":[{"id":"210400","name":"抚顺"},{"id":"210900","name":"阜新"},{"id":"341200","name":"阜阳"},{"id":"350100","name":"福州"},{"id":"350300","name":"莆田"},{"id":"361000","name":"抚州"},{"id":"440600","name":"佛山"},{"id":"450600","name":"防城港"}]},{"sortLetters":"G","data":[{"id":"360700","name":"赣州"},{"id":"440100","name":"广州"},{"id":"450300","name":"桂林"},{"id":"450800","name":"贵港"},{"id":"510800","name":"广元"},{"id":"511600","name":"广安"},{"id":"513300","name":"甘孜藏族自治州"},{"id":"520100","name":"贵阳"},{"id":"623000","name":"甘南藏族自治州"},{"id":"632600","name":"果洛藏族自治州"},{"id":"640400","name":"固原"}]},{"sortLetters":"H","data":[{"id":"130400","name":"邯郸"},{"id":"131100","name":"衡水"},{"id":"150100","name":"呼和浩特"},{"id":"150700","name":"呼伦贝尔"},{"id":"211400","name":"葫芦岛"},{"id":"230100","name":"哈尔滨"},{"id":"230400","name":"鹤岗"},{"id":"231100","name":"黑河"},{"id":"320800","name":"淮安"},{"id":"330100","name":"杭州"},{"id":"330500","name":"湖州"},{"id":"340100","name":"合肥"},{"id":"340400","name":"淮南"},{"id":"340600","name":"淮北"},{"id":"341000","name":"黄山"},{"id":"371700","name":"菏泽"},{"id":"410600","name":"鹤壁"},{"id":"420200","name":"黄石"},{"id":"421100","name":"黄冈"},{"id":"430400","name":"衡阳"},{"id":"431200","name":"怀化"},{"id":"441300","name":"惠州"},{"id":"441600","name":"河源"},{"id":"451100","name":"贺州"},{"id":"451200","name":"河池"},{"id":"460100","name":"海口"},{"id":"532500","name":"红河哈尼族彝族自治州"},{"id":"610700","name":"汉中"},{"id":"630200","name":"海东"},{"id":"632200","name":"海北藏族自治州"},{"id":"632300","name":"黄南藏族自治州"},{"id":"632500","name":"海南藏族自治州"},{"id":"632800","name":"海西蒙古族藏族自治州"},{"id":"650500","name":"哈密"},{"id":"653200","name":"和田地区"}]},{"sortLetters":"J","data":[{"id":"140500","name":"晋城"},{"id":"140700","name":"晋中"},{"id":"210700","name":"锦州"},{"id":"220200","name":"吉林"},{"id":"230300","name":"鸡西"},{"id":"230800","name":"佳木斯"},{"id":"330400","name":"嘉兴"},{"id":"330700","name":"金华"},{"id":"360200","name":"景德镇"},{"id":"360400","name":"九江"},{"id":"360800","name":"吉安"},{"id":"370100","name":"济南"},{"id":"370800","name":"济宁"},{"id":"410800","name":"焦作"},{"id":"419001","name":"济源"},{"id":"420800","name":"荆门"},{"id":"421000","name":"荆州"},{"id":"440700","name":"江门"},{"id":"445200","name":"揭阳"},{"id":"620200","name":"嘉峪关"},{"id":"620300","name":"金昌"},{"id":"620900","name":"酒泉"}]},{"sortLetters":"K","data":[{"id":"410200","name":"开封"},{"id":"530100","name":"昆明"},{"id":"659008","name":"可克达拉"},{"id":"659009","name":"昆玉"},{"id":"650200","name":"克拉玛依"},{"id":"653000","name":"克孜勒苏柯尔克孜自治州"},{"id":"653100","name":"喀什地区"}]},{"sortLetters":"L","data":[{"id":"131000","name":"廊坊"},{"id":"141000","name":"临汾"},{"id":"141100","name":"吕梁"},{"id":"211000","name":"辽阳"},{"id":"220400","name":"辽源"},{"id":"320700","name":"连云港"},{"id":"331100","name":"丽水"},{"id":"341500","name":"六安"},{"id":"350800","name":"龙岩"},{"id":"371200","name":"莱芜"},{"id":"371300","name":"临沂"},{"id":"371500","name":"聊城"},{"id":"410300","name":"洛阳"},{"id":"431300","name":"娄底"},{"id":"450200","name":"柳州"},{"id":"451300","name":"来宾"},{"id":"469027","name":"乐东黎族自治县"},{"id":"469024","name":"临高县"},{"id":"469028","name":"陵水黎族自治县"},{"id":"510500","name":"泸州"},{"id":"511100","name":"乐山"},{"id":"513400","name":"凉山彝族自治州"},{"id":"520200","name":"六盘水"},{"id":"530700","name":"丽江"},{"id":"530900","name":"临沧"},{"id":"540100","name":"拉萨"},{"id":"540400","name":"林芝"},{"id":"620100","name":"兰州"},{"id":"621200","name":"陇南"},{"id":"622900","name":"临夏回族自治州"}]},{"sortLetters":"M","data":[{"id":"231000","name":"牡丹江"},{"id":"340500","name":"马鞍山"},{"id":"440900","name":"茂名"},{"id":"441400","name":"梅州"},{"id":"510700","name":"绵阳"},{"id":"511400","name":"眉山"}]},{"sortLetters":"N","data":[{"id":"320100","name":"南京"},{"id":"320600","name":"南通"},{"id":"330200","name":"宁波"},{"id":"350700","name":"南平"},{"id":"350900","name":"宁德"},{"id":"360100","name":"南昌"},{"id":"411300","name":"南阳"},{"id":"450100","name":"南宁"},{"id":"511000","name":"内江"},{"id":"511300","name":"南充"},{"id":"533300","name":"怒江傈僳族自治州"},{"id":"542400","name":"那曲地区"}]},{"sortLetters":"P","data":[{"id":"211100","name":"盘锦"},{"id":"360300","name":"萍乡"},{"id":"410400","name":"平顶山"},{"id":"410900","name":"濮阳"},{"id":"510400","name":"攀枝花"},{"id":"530800","name":"普洱"},{"id":"620800","name":"平凉"}]},{"sortLetters":"Q","data":[{"id":"130300","name":"秦皇岛"},{"id":"230200","name":"齐齐哈尔"},{"id":"230900","name":"七台河"},{"id":"330800","name":"衢州"},{"id":"350500","name":"泉州"},{"id":"370200","name":"青岛"},{"id":"429005","name":"潜江"},{"id":"441800","name":"清远"},{"id":"450700","name":"钦州"},{"id":"469002","name":"琼海"},{"id":"469030","name":"琼中黎族苗族自治县"},{"id":"522300","name":"黔西南布依族苗族自治州"},{"id":"522600","name":"黔东南苗族侗族自治州"},{"id":"522700","name":"黔南布依族苗族自治州"},{"id":"530300","name":"曲靖"},{"id":"621000","name":"庆阳"}]},{"sortLetters":"R","data":[{"id":"371100","name":"日照"},{"id":"540200","name":"日喀则"}]},{"sortLetters":"S","data":[{"id":"320500","name":"苏州"},{"id":"130100","name":"石家庄"},{"id":"140600","name":"朔州"},{"id":"210100","name":"沈阳"},{"id":"220300","name":"四平"},{"id":"220700","name":"松原"},{"id":"230500","name":"双鸭山"},{"id":"231200","name":"绥化"},{"id":"310100","name":"上海"},{"id":"321300","name":"宿迁"},{"id":"330600","name":"绍兴"},{"id":"341300","name":"宿州"},{"id":"350200","name":"厦门"},{"id":"350400","name":"三明"},{"id":"361100","name":"上饶"},{"id":"411200","name":"三门峡"},{"id":"411400","name":"商丘"},{"id":"420300","name":"十堰"},{"id":"421300","name":"随州"},{"id":"429021","name":"神农架林区"},{"id":"430500","name":"邵阳"},{"id":"440200","name":"韶关"},{"id":"440300","name":"深圳"},{"id":"440500","name":"汕头"},{"id":"441500","name":"汕尾"},{"id":"460200","name":"三亚"},{"id":"460300","name":"三沙"},{"id":"510900","name":"遂宁"},{"id":"540500","name":"山南"},{"id":"611000","name":"商洛"},{"id":"640200","name":"石嘴山"},{"id":"659001","name":"石河子"},{"id":"659007","name":"双河"}]},{"sortLetters":"T","data":[{"id":"120100","name":"天津"},{"id":"130200","name":"唐山"},{"id":"140100","name":"太原"},{"id":"150500","name":"通辽"},{"id":"211200","name":"铁岭"},{"id":"220500","name":"通化"},{"id":"321200","name":"泰州"},{"id":"331000","name":"台州"},{"id":"340700","name":"铜陵"},{"id":"370900","name":"泰安"},{"id":"411100","name":"漯河"},{"id":"429006","name":"天门"},{"id":"469022","name":"屯昌县"},{"id":"520600","name":"铜仁"},{"id":"610200","name":"铜川"},{"id":"620500","name":"天水"},{"id":"650400","name":"吐鲁番"},{"id":"654200","name":"塔城地区"},{"id":"659006","name":"铁门关"},{"id":"659003","name":"图木舒克"}]},{"sortLetters":"W","data":[{"id":"150300","name":"乌海"},{"id":"150900","name":"乌兰察布"},{"id":"320200","name":"无锡"},{"id":"330300","name":"温州"},{"id":"340200","name":"芜湖"},{"id":"370700","name":"潍坊"},{"id":"371000","name":"威海"},{"id":"420100","name":"武汉"},{"id":"450400","name":"梧州"},{"id":"469006","name":"万宁"},{"id":"469005","name":"文昌"},{"id":"469001","name":"五指山"},{"id":"532600","name":"文山壮族苗族自治州"},{"id":"610500","name":"渭南"},{"id":"620600","name":"武威"},{"id":"640300","name":"吴忠"},{"id":"650100","name":"乌鲁木齐"},{"id":"659004","name":"五家渠"}]},{"sortLetters":"X","data":[{"id":"130500","name":"邢台"},{"id":"140900","name":"忻州"},{"id":"152200","name":"兴安盟"},{"id":"152500","name":"锡林郭勒盟"},{"id":"320300","name":"徐州"},{"id":"341800","name":"宣城"},{"id":"360500","name":"新余"},{"id":"410700","name":"新乡"},{"id":"411000","name":"许昌"},{"id":"411500","name":"信阳"},{"id":"420600","name":"襄阳"},{"id":"420900","name":"孝感"},{"id":"421200","name":"咸宁"},{"id":"429004","name":"仙桃"},{"id":"430300","name":"湘潭"},{"id":"433100","name":"湘西土家族苗族自治州"},{"id":"532800","name":"西双版纳傣族自治州"},{"id":"610100","name":"西安"},{"id":"610400","name":"咸阳"},{"id":"630100","name":"西宁"}]},{"sortLetters":"Y","data":[{"id":"140300","name":"阳泉"},{"id":"140800","name":"运城"},{"id":"210800","name":"营口"},{"id":"222400","name":"延边朝鲜族自治州"},{"id":"230700","name":"伊春"},{"id":"320900","name":"盐城"},{"id":"321000","name":"扬州"},{"id":"360600","name":"鹰潭"},{"id":"360900","name":"宜春"},{"id":"370600","name":"烟台"},{"id":"420500","name":"宜昌"},{"id":"430600","name":"岳阳"},{"id":"430900","name":"益阳"},{"id":"431100","name":"永州"},{"id":"441700","name":"阳江"},{"id":"445300","name":"云浮"},{"id":"450900","name":"玉林"},{"id":"511500","name":"宜宾"},{"id":"511800","name":"雅安"},{"id":"530400","name":"玉溪"},{"id":"610600","name":"延安"},{"id":"610800","name":"榆林"},{"id":"632700","name":"玉树藏族自治州"},{"id":"640100","name":"银川"},{"id":"654000","name":"伊犁哈萨克自治州"}]},{"sortLetters":"Z","data":[{"id":"130700","name":"张家口"},{"id":"211300","name":"朝阳"},{"id":"321100","name":"镇江"},{"id":"330900","name":"舟山"},{"id":"350600","name":"漳州"},{"id":"370300","name":"淄博"},{"id":"370400","name":"枣庄"},{"id":"410100","name":"郑州"},{"id":"411600","name":"周口"},{"id":"411700","name":"驻马店"},{"id":"430200","name":"株洲"},{"id":"430800","name":"张家界"},{"id":"440400","name":"珠海"},{"id":"440800","name":"湛江"},{"id":"441200","name":"肇庆"},{"id":"442000","name":"中山"},{"id":"500100","name":"重庆"},{"id":"500200","name":"重庆郊县"},{"id":"510300","name":"自贡"},{"id":"512000","name":"资阳"},{"id":"520300","name":"遵义"},{"id":"530600","name":"昭通"},{"id":"620700","name":"张掖"},{"id":"640500","name":"中卫"}]}]
参考了别人的代码,但他的只有点击, 我添加了一个右侧字母滑动的定位。