ListView
不分组Demo
heros.json
[
{
"image": "1.jpg",
"title": "有关斯维因的最早记载出现在诺克萨斯养老院一名医生的笔记上。据载,斯维因一瘸一拐地走进病房,没有叫喊也没有抱怨,他的右腿被折成两段,骨头破皮而出。他的肩膀上站着一只阴森的小鸟,仿佛是黏在他肩上似的...",
"name": "策士统领·斯维因"
},
{
"image": "2.jpg",
"title": "拉克丝天生就属于显赫的皇冠卫队,出自德玛西亚的模范家庭她注定要成就一番伟业。",
"name": "光辉女郎·拉克丝"
},
{
"image": "3.jpg",
"title": "古书里将其称为复仇焰魂。这个一个充满灼热仇恨的生物,它的存在就是为了将人类和约德尔人生存的地方夷为平地。",
"name": "复仇焰魂·布兰德"
},
{
"image": "4.jpg",
"title": "太阳的光芒笼罩着符文大陆,而其化身也势必如此。-蕾欧娜",
"name": "曙光女神·蕾欧娜"
},
{
"image": "5.jpg",
"title": "于生者而言,掘墓人的工作不可或缺,而在暗影岛,掘墓人的价值更不可估量",
"name": "掘墓者·约里克"
},
{
"image": "6.jpg",
"title": "通往全知的第一步是发现自己的无知。'——易大师的第一课",
"name": "齐天大圣·孙悟空"
},
{
"image": "7.jpg",
"title": "人类尚未学会控制他们的魔法——因为卡拉曼达已经变成了历史长河中的一条水晶疮疤(意指新地图水晶之痕)。",
"name": "水晶先锋·斯卡纳"
}
]
记得把图片扔到Xocde里面,Andrio以后再适配
App.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
ListView,
Image,
TouchableOpacity,
AlertIOS
} from 'react-native';
//导入json数据
var Heros = require('./heros.json');//数组
var Dimensions = require('Dimensions');
var {width} = Dimensions.get('window');
export default class ListViewTest1 extends Component {
//构造函数中初始化数据
constructor(props){
super(props);
var ds = new ListView.DataSource({rowHasChanged:(r1,r2)=>r1 !== r2});
this.state={
dataSource:ds.cloneWithRows(Heros)
};
}
render() {
return (
<ListView
style={{marginTop:25}}
dataSource = {this.state.dataSource}//设置数据源
renderRow = {this.renderRow}
/>
);
}
//返回具体的Cell
renderRow(rowData, sectionID, rowID, highlightRow){
return(
<TouchableOpacity activeOpacity={0.5}
onPress={()=>{AlertIOS.alert('购买成功!','成功解锁'+rowData.name+'英雄!')}}
>
<View style={styles.cellViewStyle}>
{/*左边的图片*/}
<Image source={{uri:rowData.image}} style={styles.leftImageStyle}/>
{/*右边的View*/}
<View style={styles.rightViewStyle}>
{/*上面是英雄名称*/}
<Text style={styles.topTitleStyle}>{rowData.name}</Text>
{/*下面是英雄描述*/}
<Text style={styles.bottomTitleStyle}
numberOfLines={3}
>{rowData.title}</Text>
</View>
</View>
</TouchableOpacity>
)
}
}
const styles = StyleSheet.create({
cellViewStyle:{
//分割线
borderBottomWidth:0.5,
borderBottomColor:'#e8e8e8',
//cell内部缩一下
padding:10,
//主轴横过来
flexDirection:'row'
},
leftImageStyle:{
width:60,
height:60,
marginRight:15
},
rightViewStyle:{
},
topTitleStyle:{
fontSize:20,
},
bottomTitleStyle:{
width:width * 0.7,
marginTop:8
}
});
分组写法
{
"data": [
{
"cars": [
{
"icon": "m_180_100.png",
"name": "AC Schnitzer"
},
{
"icon": "m_92_100.png",
"name": "阿尔法·罗密欧"
},
{
"icon": "m_9_100.png",
"name": "奥迪"
},
{
"icon": "m_97_100.png",
"name": "阿斯顿·马丁"
}
],
"title": "A"
},
{
"cars": [
{
"icon": "m_172_100.png",
"name": "巴博斯"
},
{
"icon": "m_157_100.png",
"name": "宝骏"
},
{
"icon": "m_3_100.png",
"name": "宝马"
},
{
"icon": "m_82_100.png",
"name": "保时捷"
},
{
"icon": "m_163_100.png",
"name": "北京汽车"
},
{
"icon": "m_211_100.png",
"name": "北汽幻速"
},
{
"icon": "m_168_100.png",
"name": "北汽威旺"
},
{
"icon": "m_14_100.png",
"name": "北汽制造"
},
{
"icon": "m_2_100.png",
"name": "奔驰"
},
{
"icon": "m_59_100.png",
"name": "奔腾"
},
{
"icon": "m_26_100.png",
"name": "本田"
},
{
"icon": "m_5_100.png",
"name": "标致"
},
{
"icon": "m_127_100.png",
"name": "别克"
},
{
"icon": "m_85_100.png",
"name": "宾利"
},
{
"icon": "m_15_100.png",
"name": "比亚迪"
},
{
"icon": "m_135_100.png",
"name": "布加迪"
}
],
"title": "B"
},
{
"cars": [
{
"icon": "m_129_100.png",
"name": "昌河"
}
],
"title": "C"
},
{
"cars": [
{
"icon": "m_113_100.png",
"name": "道奇"
},
{
"icon": "m_165_100.png",
"name": "大通"
},
{
"icon": "m_8_100.png",
"name": "大众"
},
{
"icon": "m_27_100.png",
"name": "东风"
},
{
"icon": "m_197_100.png",
"name": "东风风度"
},
{
"icon": "m_141_100.png",
"name": "东风风神"
},
{
"icon": "m_115_100.png",
"name": "东风风行"
},
{
"icon": "m_205_100.png",
"name": "东风小康"
},
{
"icon": "m_29_100.png",
"name": "东南"
},
{
"icon": "m_179_100.png",
"name": "DS"
}
],
"title": "D"
},
{
"cars": [
{
"icon": "m_91_100.png",
"name": "法拉利"
},
{
"icon": "m_199_100.png",
"name": "飞驰商务车"
},
{
"icon": "m_164_100.png",
"name": "菲斯克"
},
{
"icon": "m_40_100.png",
"name": "菲亚特"
},
{
"icon": "m_7_100.png",
"name": "丰田"
},
{
"icon": "m_67_100.png",
"name": "福迪"
},
{
"icon": "m_190_100.png",
"name": "弗那萨利"
},
{
"icon": "m_208_100.png",
"name": "福汽启腾"
},
{
"icon": "m_17_100.png",
"name": "福特"
},
{
"icon": "m_128_100.png",
"name": "福田"
}
],
"title": "F"
},
{
"cars": [
{
"icon": "m_109_100.png",
"name": "GMC"
},
{
"icon": "m_110_100.png",
"name": "光冈"
},
{
"icon": "m_147_100.png",
"name": "广汽"
},
{
"icon": "m_63_100.png",
"name": "广汽吉奥"
},
{
"icon": "m_133_100.png",
"name": "广汽日野"
},
{
"icon": "m_182_100.png",
"name": "观致汽车"
}
],
"title": "G"
},
{
"cars": [
{
"icon": "m_31_100.png",
"name": "哈飞"
},
{
"icon": "m_196_100.png",
"name": "哈弗"
},
{
"icon": "m_170_100.png",
"name": "海格"
},
{
"icon": "m_32_100.png",
"name": "海马"
},
{
"icon": "m_149_100.png",
"name": "海马商用车"
},
{
"icon": "m_181_100.png",
"name": "恒天汽车"
},
{
"icon": "m_58_100.png",
"name": "红旗"
},
{
"icon": "m_52_100.png",
"name": "黄海"
},
{
"icon": "m_112_100.png",
"name": "华泰"
},
{
"icon": "m_45_100.png",
"name": "汇众"
}
],
"title": "H"
},
{
"cars": [
{
"icon": "m_35_100.png",
"name": "江淮"
},
{
"icon": "m_37_100.png",
"name": "江铃"
},
{
"icon": "m_38_100.png",
"name": "江南"
},
{
"icon": "m_98_100.png",
"name": "捷豹"
},
{
"icon": "m_143_100.png",
"name": "吉利帝豪"
},
{
"icon": "m_144_100.png",
"name": "吉利全球鹰"
},
{
"icon": "m_148_100.png",
"name": "吉利英伦"
},
{
"icon": "m_39_100.png",
"name": "金杯"
},
{
"icon": "m_57_100.png",
"name": "金龙联合"
},
{
"icon": "m_161_100.png",
"name": "金旅客车"
},
{
"icon": "m_152_100.png",
"name": "九龙"
},
{
"icon": "m_4_100.png",
"name": "Jeep"
}
],
"title": "J"
},
{
"cars": [
{
"icon": "m_188_100.png",
"name": "卡尔森"
},
{
"icon": "m_107_100.png",
"name": "凯迪拉克"
},
{
"icon": "m_150_100.png",
"name": "开瑞"
},
{
"icon": "m_51_100.png",
"name": "克莱斯勒"
},
{
"icon": "m_145_100.png",
"name": "科尼塞克"
},
{
"icon": "m_212_100.png",
"name": "KTM"
}
],
"title": "K"
},
{
"cars": [
{
"icon": "m_86_100.png",
"name": "兰博基尼"
},
{
"icon": "m_200_100.png",
"name": "蓝海房车"
},
{
"icon": "m_80_100.png",
"name": "劳斯莱斯"
},
{
"icon": "m_94_100.png",
"name": "雷克萨斯"
},
{
"icon": "m_99_100.png",
"name": "雷诺"
},
{
"icon": "m_146_100.png",
"name": "莲花"
},
{
"icon": "m_153_100.png",
"name": "猎豹汽车"
},
{
"icon": "m_76_100.png",
"name": "力帆"
},
{
"icon": "m_16_100.png",
"name": "铃木"
},
{
"icon": "m_166_100.png",
"name": "理念"
},
{
"icon": "m_95_100.png",
"name": "林肯"
},
{
"icon": "m_36_100.png",
"name": "陆风"
},
{
"icon": "m_96_100.png",
"name": "路虎"
},
{
"icon": "m_83_100.png",
"name": "路特斯"
}
],
"title": "L"
},
{
"cars": [
{
"icon": "m_183_100.png",
"name": "迈凯伦"
},
{
"icon": "m_93_100.png",
"name": "玛莎拉蒂"
},
{
"icon": "m_18_100.png",
"name": "马自达"
},
{
"icon": "m_79_100.png",
"name": "MG"
},
{
"icon": "m_81_100.png",
"name": "MINI"
},
{
"icon": "m_201_100.png",
"name": "摩根"
}
],
"title": "M"
},
{
"cars": [
{
"icon": "m_155_100.png",
"name": "纳智捷"
}
],
"title": "N"
},
{
"cars": [
{
"icon": "m_104_100.png",
"name": "欧宝"
},
{
"icon": "m_84_100.png",
"name": "讴歌"
},
{
"icon": "m_171_100.png",
"name": "欧朗"
}
],
"title": "O"
},
{
"cars": [
{
"icon": "m_156_100.png",
"name": "启辰"
},
{
"icon": "m_43_100.png",
"name": "庆铃"
},
{
"icon": "m_42_100.png",
"name": "奇瑞"
},
{
"icon": "m_28_100.png",
"name": "起亚"
}
],
"title": "Q"
},
{
"cars": [
{
"icon": "m_30_100.png",
"name": "日产"
},
{
"icon": "m_78_100.png",
"name": "荣威"
},
{
"icon": "m_142_100.png",
"name": "瑞麒"
}
],
"title": "R"
},
{
"cars": [
{
"icon": "m_25_100.png",
"name": "三菱"
},
{
"icon": "m_209_100.png",
"name": "山姆"
},
{
"icon": "m_195_100.png",
"name": "绅宝"
},
{
"icon": "m_50_100.png",
"name": "双环"
},
{
"icon": "m_102_100.png",
"name": "双龙"
},
{
"icon": "m_111_100.png",
"name": "斯巴鲁"
},
{
"icon": "m_10_100.png",
"name": "斯柯达"
},
{
"icon": "m_89_100.png",
"name": "smart"
}
],
"title": "S"
},
{
"cars": [
{
"icon": "m_202_100.png",
"name": "泰卡特"
},
{
"icon": "m_189_100.png",
"name": "特斯拉"
}
],
"title": "T"
},
{
"cars": [
{
"icon": "m_140_100.png",
"name": "威麟"
},
{
"icon": "m_186_100.png",
"name": "威兹曼"
},
{
"icon": "m_19_100.png",
"name": "沃尔沃"
},
{
"icon": "m_48_100.png",
"name": "五菱"
}
],
"title": "W"
},
{
"cars": [
{
"icon": "m_13_100.png",
"name": "现代"
},
{
"icon": "m_174_100.png",
"name": "星客特"
},
{
"icon": "m_71_100.png",
"name": "新凯"
},
{
"icon": "m_87_100.png",
"name": "西雅特"
},
{
"icon": "m_49_100.png",
"name": "雪佛兰"
},
{
"icon": "m_6_100.png",
"name": "雪铁龙"
}
],
"title": "X"
},
{
"cars": [
{
"icon": "m_194_100.png",
"name": "扬州亚星客车"
},
{
"icon": "m_138_100.png",
"name": "野马汽车"
},
{
"icon": "m_100_100.png",
"name": "英菲尼迪"
},
{
"icon": "m_53_100.png",
"name": "一汽"
},
{
"icon": "m_41_100.png",
"name": "依维柯"
},
{
"icon": "m_75_100.png",
"name": "永源"
}
],
"title": "Y"
},
{
"cars": [
{
"icon": "m_136_100.png",
"name": "长安轿车"
},
{
"icon": "m_159_100.png",
"name": "长安商用"
},
{
"icon": "m_21_100.png",
"name": "长城"
},
{
"icon": "m_203_100.png",
"name": "之诺"
},
{
"icon": "m_60_100.png",
"name": "中华"
},
{
"icon": "m_167_100.png",
"name": "中欧"
},
{
"icon": "m_77_100.png",
"name": "众泰"
},
{
"icon": "m_204_100.png",
"name": "中通客车"
},
{
"icon": "m_33_100.png",
"name": "中兴"
}
],
"title": "Z"
}
]
}
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
/**
* cloneWithRowsAndSections(dataBlob, sectionIdentities, rowIdentities)
* dataBlob 就是数据!具体类型是一个对象Object!
* sectionID 哪一组!
* rowID 哪一行!
* */
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
ListView,
Image,
TouchableOpacity,
} from 'react-native';
var Car = require('./Car.json');
export default class ListViewTest2 extends Component {
//构造函数
constructor(props){
super(props);
var getSectionData = (dataBlob,sectionID)=>{
return dataBlob[sectionID];
};
var getRowData = (dataBlob,sectionID,rowID) =>{
return dataBlob[sectionID+':'+rowID];
};
this.state={
dataSource:new ListView.DataSource({
getSectionData:getSectionData,//获取组数据
getRowData:getRowData,//获取数据
rowHasChanged:(r1,r2) => r1 !== r2,
sectionHeaderHasChanged:(s1,s2) => s1 !== s2
})
}
}
render() {
return (
<View style={styles.container}>
{/*头部Nav*/}
<View style={styles.NavViewStyle}>
<Text style={{color:'white',fontSize:25}}>这是汽车品牌展示</Text>
</View>
{/*ListView*/}
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
renderSectionHeader={this.renderSectionHeader}
/>
</View>
);
}
//返回每一组头部的内容
renderSectionHeader(sectionData,sectionID){
return(
<View style={styles.sectionHeaderStyle}>
<Text style={{marginLeft:5,color:'red'}}>{sectionData}</Text>
</View>
)
}
//返回每一行Cell
renderRow(rowData){
return(
<TouchableOpacity activeOpacity={0.5}>
<View style={styles.rowStyle}>
<Image source={{uri:rowData.icon}} style={styles.rowImageStyle}/>
<Text style={{marginLeft:5}}>{rowData.name}</Text>
</View>
</TouchableOpacity>
)
}
//发送网络请求的生命周期方法
componentDidMount(){
//数据我们需要先处理
this.loadJson();
}
loadJson(){
//拿到Json
var jsonData = Car.data;
//定义数据源需要的变量
var dataBlob = {},
sectionIDs = [],
rowIDs = [],//二维数组!!
cars = [];
//遍历
for(var i=0;i<jsonData.length;i++){
//1.组ID拿到
sectionIDs.push(i);
//2.dataBlob
dataBlob[i] = jsonData[i].title;
//3.取出这一组的所有的车
cars = jsonData[i].cars;
rowIDs[i] = [];
for (var j=0;j<cars.length;j++){
//i组的j行 那么这一行的ID 就是 j
rowIDs[i].push(j);
//每一行的内容放到dataBlob里面了!!
dataBlob[i+':'+j] = cars[j];
}
}
//更新状态机!!
this.setState({
dataSource:this.state.dataSource.cloneWithRowsAndSections(dataBlob,sectionIDs,rowIDs)
})
}
}
const styles = StyleSheet.create({
container:{
flex:1,
},
NavViewStyle:{
height:64,
backgroundColor:'orange',
justifyContent:'center',
alignItems:'center',
},
rowStyle: {
padding:10,
flexDirection:'row',
alignItems:'center',
//cell分割线
borderBottomColor:'#e8e8e8',
borderBottomWidth:0.5
},
rowImageStyle:{
width:70,
height:70
},
sectionHeaderStyle:{
backgroundColor:'#e8e8e8',
height:25,
justifyContent:'center',
}
});
FlatList
V0.45之后,ListView组件被废除此组件已过期 - 请使用FlatList或SectionList代替。
高性能的简单列表组件,支持下面这些常用的功能:
完全跨平台。
支持水平布局模式。
行组件显示或隐藏时可配置回调事件。
支持单独的头部组件。
支持单独的尾部组件。
支持自定义行间分隔线。
支持下拉刷新。
支持上拉加载。
如果需要分组/类/区(section),请使用 SectionList
ItemSeparatorComponent:分割线组件,
ListFooterComponent:结尾组件
ListHeaderComponent:头组件
data:列表数据
horizontal:设置为true则变为水平列表。
numColumns:列数 组件内元素必须是等高的,无法支持瀑布流布局
columnWrapperStyle:numColumns大于1时,设置每行的样式
getItemLayout:如果我们知道行高可以用此方法节省动态计算行高的开销。
refreshing:是否正在加载数据
onRefresh:设置此属性需要一个标准的 RefreshControl 控件,刷新数据
renderItem:渲染每个组件
onViewableItemsChanged:当一个新的Item渲染或者隐藏 的时候调用此方法。参数:info: {viewableItems: Array, changed: Array} viewableItems:当前可见的Item,changed:渲染或者隐藏的Item。
scrollToEnd({params?: ?{animated?: ?boolean}}):滚动到末尾,如果不设置getItemLayout属性的话,可能会比较卡。
scrollToIndexparams: {animated?: ?boolean, index: number, viewPosition?: number}:滚动到制定的位置
scrollToOffset(params: {animated?: ?boolean, offset: number}):滚动到指定的偏移的位置。
import React, {Component} from 'react';
import {
StyleSheet,
View,
FlatList,
Text,
Button,
} from 'react-native';
var ITEM_HEIGHT = 100;
export default class FlatListDemo extends Component {
_flatList;
_renderItem = (item) => {
var txt = '第' + item.index + '个' + ' title=' + item.item.title;
var bgColor = item.index % 2 == 0 ? 'red' : 'blue';
return <Text style={[{flex:1,height:ITEM_HEIGHT,backgroundColor:bgColor},styles.txt]}>{txt}</Text>
}
_header = () => {
return <Text style={[styles.txt,{backgroundColor:'black'}]}>这是头部</Text>;
}
_footer = () => {
return <Text style={[styles.txt,{backgroundColor:'black'}]}>这是尾部</Text>;
}
_separator = () => {
return <View style={{height:2,backgroundColor:'yellow'}}/>;
}
render() {
var data = [];
for (var i = 0; i < 100; i++) {
data.push({key: i, title: i + ''});
}
return (
<View style={{flex:1}}>
<Button title='滚动到指定位置' onPress={()=>{
this._flatList.scrollToEnd();
{/*this._flatList.scrollToIndex({viewPosition:2,index:8});*/}
{/*this._flatList.scrollToOffset({animated: true, offset: 2000});*/}
}}/>
<View style={{flex:1}}>
<FlatList
ref={(flatList)=>this._flatList = flatList}
ListHeaderComponent={this._header}
ListFooterComponent={this._footer}
ItemSeparatorComponent={this._separator}
renderItem={this._renderItem}
data={data}>
</FlatList>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
txt: {
textAlign: 'center',
textAlignVertical: 'center',
color: 'white',
fontSize: 30,
}
});
SectionList
SectionSeparatorComponent:组之间的分割控件
renderSectionHeader:组的头部
sections:列表的数据
import React, {Component} from 'react';
import {
StyleSheet,
View,
Text,
SectionList,
} from 'react-native';
export default class SectionListDemo extends Component {
_renderItem = (info) => {
var txt = 'index:' + info.index + ' ' + info.item.title;
var bgColor = info.index % 2 == 0 ? 'red' : 'blue';
return <Text
style={{height:100,textAlignVertical:'center',backgroundColor:bgColor,color:'white',fontSize:15}}>{txt}</Text>
}
_sectionComp = (info) => {
var txt = 'key:' + info.section.key;
return <Text
style={{height:50,textAlign:'center',textAlignVertical:'center',backgroundColor:'black',color:'white',fontSize:30}}>{txt}</Text>
}
render() {
var sections = [];
for (var i = 0; i < 10; i++) {
var datas = [];
for (var j = 0; j < 10; j++) {
datas.push({title: 'title:' + j});
}
sections.push({key: i, data: datas});
}
return (
<View style={{flex:1}}>
<SectionList
renderSectionHeader={this._sectionComp}
renderItem={this._renderItem}
sections={sections}/>
</View>
);
}
}