商品界面实现起来很简单,其实就是一个listview的使用:
关于listview的使用,在官方文档里面已经介绍的很详细了。在这里我要提一个坑。
listview在Android和iOS中的效果是不一样的,listview对iOS的支持已经很好了,但是对android很多属性都不支持。有些地方官方文档也说的模棱两可的,因此如果想做炫酷的上、下拉效果的话,建议做iOS。
下面看一下代码吧:
1 'use strict' 2 3 var React = require('react-native') 4 import Icon from 'react-native-vector-icons/FontAwesome' 5 import AniImage from '../components/AniImage' 6 import AniRoll from '../components/AniRoll' 7 var { 8 Image, 9 ListView, 10 StyleSheet, 11 Text, 12 View, 13 TouchableOpacity, 14 Navigator, 15 PropTypes 16 } = React 17 18 var REQUEST_URL = 'http://192.168.6.5:8888/getCommidity' 19 20 class Commodity extends React.Component { 21 static propTypes = { 22 navigator: PropTypes.object, 23 fetch: PropTypes.func 24 }; 25 constructor (props) { 26 super(props) 27 this.state = { 28 dataSource: new ListView.DataSource({ 29 rowHasChanged: (row1, row2) => row1 !== row2 30 }), 31 loaded: false 32 } 33 } 34 componentDidMount () { 35 this.fetchData() 36 } 37 38 fetchData () { 39 fetch (REQUEST_URL) 40 .then((response) => response.json()) 41 .then((responseData) => { 42 this.setState({ 43 dataSource: this.state.dataSource.cloneWithRows(responseData), 44 loaded: true 45 }) 46 }) 47 .done() 48 } 49 50 render () { 51 if (!this.state.loaded) { 52 return this.renderLoadingView() 53 } 54 55 return ( 56 <ListView 57 initialListSize={3} 58 dataSource={this.state.dataSource} 59 renderRow={this.renderCommidity.bind(this)} 60 style={styles.listView}/> 61 ) 62 } 63 64 renderLoadingView () { 65 return ( 66 <View style={styles.txtContainer}> 67 <AniRoll inputRange={[0, 1]} outputRange={['0deg', '10000deg']} style={{ 50, height: 50}} /> 68 <Text> 69 正在加载图文。。。 70 </Text> 71 </View> 72 ) 73 } 74 75 renderCommidity (commidities) { 76 return ( 77 <View style={styles.container} > 78 <Image style={styles.viewTopImage} source={require('../assets/listbg.png')}> 79 <TouchableOpacity onPress={this.toCommodityScreen.bind(this, commidities)}> 80 <AniImage 81 type={'image'} 82 inputRange={[0, 100]} 83 outputRange={[0, 1]} 84 style={styles.aniImage} 85 url={'http://192.168.6.5:8888/getImage?imgName=' + commidities.imgPath1} /> 86 </TouchableOpacity> 87 </Image> 88 <View style={styles.viewTxtContent}> 89 <TouchableOpacity> 90 <Text style={styles.txtContent}>{commidities.title}</Text> 91 </TouchableOpacity> 92 </View> 93 <View style={styles.viewBottom}> 94 <View style={styles.viewBottomLeft}> 95 <Icon name='heart-o' size={20} /> 96 <Text style={styles.txtContent} >{commidities.love}</Text> 97 </View> 98 <View style={styles.viewBottomRight}> 99 <View style={styles.viewBottomRightContainer}> 100 <Icon name='clock-o' size={20} /> 101 <Text style={styles.txtContent} >{commidities.date}</Text> 102 </View> 103 </View> 104 </View> 105 <Image source={require('../assets/splite.png')} style={styles.imageSplit}/> 106 </View> 107 ) 108 } 109 110 toCommodityScreen (commidities) { 111 var commodity = commidities 112 let navigator = this.props.navigator 113 navigator.push({id: 'CommodityScreen', sceneConfig: Navigator.SceneConfigs.HorizontalSwipeJump, passProp: {commodity}}) 114 } 115 } 116 117 var styles = StyleSheet.create({ 118 container: { 119 flex: 1, 120 flexDirection: 'column', 121 backgroundColor: '#ffffff' 122 }, 123 txtContainer: { 124 flex: 1, 125 alignItems: 'center', 126 justifyContent: 'center', 127 backgroundColor: '#fffff' 128 }, 129 aniImage: { 130 height: 330, 131 null 132 }, 133 viewTopImage: { 134 height: 330, 135 null, 136 margin: 10 137 }, 138 txtContent: { 139 fontSize: 16, 140 marginLeft: 5 141 }, 142 viewTxtContent: { 143 marginLeft: 10, 144 marginRight: 10, 145 marginBottom: 5, 146 flex: 1 147 }, 148 txtBottom: { 149 flex: 1, 150 fontSize: 12 151 }, 152 viewBottom: { 153 marginLeft: 10, 154 marginRight: 10, 155 marginBottom: 5, 156 flex: 1, 157 flexDirection: 'row' 158 }, 159 imageSplit: { 160 flex: 0.3, 161 backgroundColor: '#F0F0F0' 162 }, 163 numberText: { 164 fontSize: 15, 165 marginLeft: 20 166 }, 167 viewBottomLeft: { 168 flex: 1, 169 flexDirection: 'row' 170 }, 171 viewBottomRight: { 172 flex: 1, 173 alignItems: 'flex-end' 174 }, 175 viewBottomRightContainer: { 176 flex: 1, 177 flexDirection: 'row' 178 } 179 }) 180 181 module.exports = Commodity
一、构造方法:
1 constructor (props) { 2 super(props) 3 this.state = { 4 dataSource: new ListView.DataSource({ 5 rowHasChanged: (row1, row2) => row1 !== row2 6 }), 7 loaded: false 8 } 9 }
dataSource就是listview的数据源,loaded则是判断数据是否加载完毕。
二、fetchData方法
获取listview的接口数据,数据请求完成之后,重新渲染界面将loaded设置为true
三、toCommodityScreen方法
进入商品的详情界面。