react native带索引的城市列表组件的实例代码

前端之家收集整理的这篇文章主要介绍了react native带索引的城市列表组件的实例代码前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

城市列表选择是很多app共有的功能,比如典型的美图app。那么对于React Native怎么实现呢?

这里写图片描述

要实现上面的效果,首先需要对界面的组成简单分析,界面的数据主要由当前城市,历史访问城市和热门城市组成,所以我们在提供Json数据的时候就需要将数据分为至少3部分。

而要实现字母索引功能,我们需要自定义一个控件,实现和数据的绑定关系,自定义组件代码如下:

CityIndexListView.js

import Toast,{DURATION} from './ToastUtil'

const SECTIONHEIGHT = 30;
const ROWHEIGHT = 40;
const ROWHEIGHT_BOX = 40;
var totalheight = []; //每个字母对应的城市和字母的总高度

const {width,height} = Dimensions.get('window');

var that;

const key_now = '当前';
const key_last_visit = '最近';
const key_hot = '热门';

export default class CityIndexListView extends Component {

constructor(props) {
super(props);

var getSectionData = (dataBlob,sectionID) => {
  return sectionID;
};
var getRowData = (dataBlob,sectionID,rowID) => {
  return dataBlob[sectionID][rowID];
};

let ALL_CITY_LIST = this.props.allCityList;
let CURRENT_CITY_LIST = this.props.nowCityList;
let LAST_VISIT_CITY_LIST = this.props.lastVisitCityList;
let HOT_CITY_LIST = this.props.hotCityList;

let letterList = this._getSortLetters(ALL_CITY_LIST);

let dataBlob = {};
dataBlob[key_now] = CURRENT_CITY_LIST;
dataBlob[key_last_visit] = LAST_VISIT_CITY_LIST;
dataBlob[key_hot] = HOT_CITY_LIST;

ALL_CITY_LIST.map(cityJson => {
  let key = cityJson.sortLetters.toUpperCase();

  if (dataBlob[key]) {
    let subList = dataBlob[key];
    subList.push(cityJson);
  } else {
    let subList = [];
    subList.push(cityJson);
    dataBlob[key] = subList;
  }
});

let sectionIDs = Object.keys(dataBlob);
let rowIDs = sectionIDs.map(sectionID => {
  let thisRow = [];
  let count = dataBlob[sectionID].length;
  for (let ii = 0; ii < count; ii++) {
    thisRow.push(ii);
  }

  let eachheight = SECTIONHEIGHT + ROWHEIGHT * thisRow.length;
  if (sectionID === key_hot || sectionID === key_now || sectionID === key_last_visit) {
    let rowNum = (thisRow.length % 3 === 0)
      ? (thisRow.length / 3)
      : parseInt(thisRow.length / 3) + 1;

    console.log('sectionIDs===>' + sectionIDs + ",rowNum=====>" + rowNum);

    eachheight = SECTIONHEIGHT + ROWHEIGHT_<a href="/tag/Box/" target="_blank" class="keywords">Box</a> * rowNum;
  }

  totalheight.push(eachheight);

  return thisRow;
});


let ds = new ListView.DataSource({
  getRowData: getRowData,getSectionHeaderData: getSectionData,rowHasChanged: (row1,row2) => row1 !== row2,sectionHeaderHasChanged: (s1,s2) => s1 !== s2
});

this.state = {
  dataSource: ds.cloneWithRowsAndSections(dataBlob,sectionIDs,rowIDs),letters: sectionIDs
};

that = this;

}

_getSortLetters(dataList) {
let list = [];

for (let j = 0; j < dataList.length; j++) {
  let sortLetters = dataList[j].sortLetters.toUpperCase();

  let exist = false;
  for (let xx = 0; xx < list.length; xx++) {
    if (list[xx] === sortLetters) {
      exist = true;
    }
    if (exist) {
      break;
    }
  }
  if (!exist) {
    list.push(sortLetters);
  }
}

return list;

}

_cityNameClick(cityJson) {
// alert('选择了城市====》' + cityJson.id + '#####' + cityJson.name);
this.props.onSelectCity(cityJson);
}

_scrollTo(index,letter) {
this.refs.toast.close();
let position = 0;
for (let i = 0; i < index; i++) {
position += totalheight[i]
}
this._listView.scrollTo({y: position});
this.refs.toast.show(letter,DURATION.LENGTH_SHORT);
}

_renderRightLetters(letter,index) {
return (
<TouchableOpacity key={'letteridx' + index} activeOpacity={0.6} onPress={() => {
this._scrollTo(index,letter)
}}>

{letter} ); }

_renderListBox(cityJson,rowId) {
return (
<TouchableOpacity key={'listitem' + cityJson.id} style={styles.rowViewBox} onPress={() => {
that._cityNameClick(cityJson)
}}>

{cityJson.name} ); }

_renderListRow(cityJson,rowId) {
console.log('rowId===>' + rowId + ",cityJson====>" + JSON.stringify(cityJson));
if (rowId === key_now || rowId === key_hot || rowId === key_last_visit) {
return that._renderListBox(cityJson,rowId);
}

return (
  <TouchableOpacity key={'list_item_' + cityJson.id} style={styles.rowView} onPress={() => {
    that._cityNameClick(cityJson)
  }}>
    <View style={styles.rowdata}>
      <Text style={styles.rowdatatext}>{cityJson.name}</Text>
    </View>
  </TouchableOpacity>
)

}

_renderListSectionHeader(sectionData,sectionID) {
return (

{sectionData} ); }

render() {
return (

this._listView = listView} contentContainerStyle={styles.contentContainer} dataSource={this.state.dataSource} renderRow={this._renderListRow} renderSectionHeader={this._renderListSectionHeader} enableEmptySections={true} initialListSize={500}/> {this.state.letters.map((letter,index) => this._renderRightLetters(letter,index))} ) } }

const styles = StyleSheet.create({
container: {
// paddingTop: 50,flex: 1,flexDirection: 'column',backgroundColor: '#F4F4F4',},listContainner: {
height: Dimensions.get('window').height,marginBottom: 10
},contentContainer: {
flexDirection: 'row',width: width,backgroundColor: 'white',justifyContent: 'flex-start',flexWrap: 'wrap'
},letters: {
position: 'absolute',height: height,top: 0,bottom: 0,right: 10,backgroundColor: 'transparent',// justifyContent: 'flex-start',// alignItems: 'flex-start'
alignItems: 'center',justifyContent: 'center'
},letter: {
height: height 4 / 100,width: width 4 / 50,justifyContent: 'center',alignItems: 'center'
},letterText: {
textAlign: 'center',fontSize: height * 1.1 / 50,color: '#e75404'
},sectionView: {
paddingTop: 5,paddingBottom: 5,height: 30,paddingLeft: 10,backgroundColor: '#F4F4F4'
},sectionText: {
color: '#e75404',fontWeight: 'bold'
},rowView: {
height: ROWHEIGHT,paddingRight: 10,borderBottomColor: '#F4F4F4',borderBottomWidth: 0.5
},rowdata: {
paddingTop: 10,paddingBottom: 2
},rowdatatext: {
color: 'gray',width: width
},rowViewBox: {
height: ROWHEIGHT_Box,width: (width - 30) / 3,flexDirection: 'row',backgroundColor: '#ffffff'
},rowdataBox: {
borderWidth: 1,borderColor: '#DBDBDB',marginTop: 5,marginBottom: 5,paddingBottom: 2,marginLeft: 10,marginRight: 10,rowDataTextBox: {
marginTop: 5,height: 20
}

});

然后在头部还需要实现一个搜索框。

SearchBox.js

export default class SearchBox extends Component {
constructor(props) {
super(props);
this.state = {
value: ''
};

}

onEndEditingKeyword(vv) {
console.log(vv);
}

onChanegeTextKeyword(vv) {
console.log('onChanegeTextKeyword',vv);

this.setState({value: vv});
this.props.onChanegeTextKeyword(vv);

}

render() {
return (

) } }

const styles = StyleSheet.create({
container: {
marginTop: 5,backgroundColor: '#ffffff',height: Platform.OS === 'ios'
? 35
: 45,borderBottomWidth: StyleSheet.hairlineWidth,borderBottomColor: '#cdcdcd',paddingBottom: 5
},inputBox: {
height: Platform.OS === 'ios'
? 30
: 40,marginLeft: 5,marginRight: 5,backgroundColor: '#E6E7E8'
},inputIcon: {
margin: Platform.OS === 'ios'
? 5
: 10
},inputText: {
alignSelf: 'flex-end',marginTop: Platform.OS === 'ios'
? 0
: 0,height: Platform.OS === 'ios'
? 30
: 40,marginLeft: 2,fontSize: 12,lineHeight: 30,textAlignVertical: 'bottom',textDecorationLine: 'none'
}
});

最终效果

这里写图片描述

这里写图片描述

最后是界面的绘制,这里就不多说了,大家可以下载源码自行查看。源码地址:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

猜你在找的JavaScript相关文章