我们今天完成的效果就是这张图中标注的地方
Home.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow
* @lint-ignore-every XPLATJSCOPYRIGHT1
*/
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, ScrollView,View,TextInput,Image,StatusBar} from 'react-native';
import HomeDetail from './HomeDetail';
var Dimensions =require('Dimensions')
var {width, height} = Dimensions.get('window');
import HomeTopView from './HomeTopView'
export default class Home extends Component<Props> {
_pressButton(){
const {navigator} = this.props;
if (navigator) {
//startActivity
navigator.push({
name:"详情页面",
component:HomeDetail
})
}
}
render() {
return (
<View>
<StatusBar
backgroundColor='rgba(255,96,0,1.0)'
barStyle="light-content"
/>
{this.renderNavBar()}
//这里要使用ScrollView包裹,不然显示不出来组件:
//这个地方好坑,我查了半个多小时才查出来的。
<ScrollView>
<HomeTopView/>
</ScrollView>
</View>
);
}
renderNavBar() {
return (
<View style={styles.navBarStyle}>
<Text>
长沙
</Text>
<TextInput
placeholder="养生" style={styles.topInputStyle}></TextInput>
<View style={{flexDirection:'row'}}>
<Image source={require('../../res/images/icon_homepage_message.png')} style={styles.navRightImg}/>
<Image source={require('../../res/images/icon_homepage_scan.png')} style={styles.navRightImg}/>
</View>
</View>
)
}
}
const styles = StyleSheet.create({
navBarStyle:{
backgroundColor:'rgba(255,96,0,1.0)',
height:60,
flexDirection:'row',
alignItems: 'center',
justifyContent:'space-around',
position:'relative',
top:-10
},
navRightImg:{
width:30,
height:30
},
topInputStyle:{
width:width*0.7,
height:40,
backgroundColor: 'white',
borderRadius:16,
paddingLeft:10
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow
* @lint-ignore-every XPLATJSCOPYRIGHT1
*/
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View,TextInput,Image,StatusBar,ScrollView} from 'react-native';
var Dimensions =require('Dimensions')
var {width, height} = Dimensions.get('window');
import HomeTopListView from './HomeTopListView'
export default class HomeTopView extends Component<Props> {
constructor(Props) {
super(Props);
//二维json数组,实际开发中是通过网络请求得到的
const data = [[
{"title": "美食", "image": require('../../res/images/ms.png')},
{"title": "电影", "image": require('../../res/images/dy.png')},
{"title": "酒店", "image": require('../../res/images/jd.png')},
{"title": "休闲娱乐", "image": require('../../res/images/xxyl.png')},
{"title": "外卖", "image": require('../../res/images/wm.png')},
{"title": "自助餐", "image": require('../../res/images/zzc.png')},
{"title": "KTV", "image": require('../../res/images/ktv.png')},
{"title": "火车票机票", "image": require('../../res/images/hcpjp.png')},
{"title": "丽人", "image": require('../../res/images/lr.png')},
{"title": "周边游", "image": require('../../res/images/zby.png')}], [
{"title": "足疗按摩", "image": require('../../res/images/zlam.png')},
{"title": "购物", "image": require('../../res/images/gw.png')},
{"title": "今日新单", "image": require('../../res/images/jrxd.png')},
{"title": "小吃快餐", "image": require('../../res/images/xckc.png')},
{"title": "生活服务", "image": require('../../res/images/shfw.png')},
{"title": "甜点饮品", "image": require('../../res/images/tdyp.png')},
{"title": "美甲", "image": require('../../res/images/mj.png')},
{"title": "景点门票", "image": require('../../res/images/jdmp.png')},
{"title": "旅游", "image": require('../../res/images/ly.png')},
{"title": "全部分类", "image": require('../../res/images/qbfl.png')}]
];
//通过网络请求获取到的数据并且传输到了该组件,
this.state={
//键值同名可以这么写,相当于
//data:data
data,
currenentPage:0
}
}
renderScrollItem(){
var itemArr=[];
for (var i = 0; i < this.state.data.length; i++) {
itemArr.push(<HomeTopListView key={i} dataArr={this.state.data[i]}/>)
}
return itemArr;
}
renderIndicator(){
var indicatorArr=[];
// var number '10' ==number2 10
for (var i = 0; i < 2; i++) {
//== 一般等于 ====严格等于
//定义样式:
var style=(i==this.state.currenentPage)?{color:'red'}:{color:'gray'}
//•表示显示点号
//把我们自己定义的stydle加进去,这是es6的写法
indicatorArr.push(<Text key={i} style={[{fontSize:25},style]}>•</Text>)
}
return indicatorArr;
}
render() {
return (
<View style={styles.containStyle}>
//RN中没有ViewPager,但可以通过ScrollView来实现,
//ScrollView不仅可以竖向滚动,还可以横向滚动。
<ScrollView horizontal={true}//设置为横向滚动
pagingEnabled={true}//设置为整个页面滚动,类似于ViewPager效果,不设置就是RecyclerView横向滑动的效果
showsHorizontalScrollIndicator={false}//去掉下划线
//ScrollView滚动动画结束的时候调用该函数,相当于设置监听的接口
onMomentumScrollEnd={(e)=>{
//e.nativeEvent.contentOffset.x:表示x轴的偏移量;除以with就可以算出当前页
this.setState({currenentPage:(e.nativeEvent.contentOffset.x/width-1)})
}}
>
//
{this.renderScrollItem()}
</ScrollView>
//点号:需要与ScrollView联动
<View style={styles.indicatorStyle}>
{this.renderIndicator()}
</View>
</View>
);
}
}
const styles = StyleSheet.create({
indicatorStyle:{
flexDirection:'row',
justifyContent:'center'
},
containStyle:{
flex:1,
justifyContent:'center',
alignItems:'center',
backgroundColor:'#F5FCFF'
}
});
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow
* @lint-ignore-every XPLATJSCOPYRIGHT1
*/
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View,TextInput,Image,StatusBar,ListView} from 'react-native';
var Dimensions =require('Dimensions')
var {width, height} = Dimensions.get('window');
export default class HomeTopListView extends Component<Props> {
constructor(Props) {
super(Props);
//1,为ListView设置数据源。
//2,{rowHasChanged: (row1, row2) => row1 !== row2}代表数据源
//的规则,如果旧的row1,不等于新的row2,那么就会rowHasChanged。
var ds=new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2})
this.state={
//this.props.dataArr;是外部传进来的
//数据源传递进去了数据this.props.dataArr;并赋值到ds里面,
dataSource :ds.cloneWithRows(this.props.dataArr)
}
}
render() {
return (
//不能写死,比如我们需求改了,图标改成了四个,所以我们要使用ListView加载
<ListView
dataSource={this.state.dataSource}
//ListView的样式
contentContainerStyle={styles.contentContainerStyle}
//这个函数会接受数组中的每个数据作为参数,返回一个可渲染的组件(作为ListView的每一行)
renderRow={(rowData)=><View style={styles.cellStyle}><Image style={{width:60,height:60}} source={rowData.image}/><Text>{rowData.title}</Text></View>}
/>
);
}
}
const styles = StyleSheet.create({
cellStyle:{
width:80,
height:80,
alignItems:'center',
justifyContent:'center',
marginTop: 10,
},
contentContainerStyle:{
//ListtView的方向
flexDirection:'row',
//能不能自动换行,第一行排满了会自动换到第二行
flexWrap:'wrap',
width:width,
}
});