王学岗ReactNative开发8——项目实战三之主页中间以及FlastList以及网络请求
第一:主页中间
这张图片是我们要实现的效果
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'
import HomeMiddleView from './HomeMiddleView'
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>
<HomeTopView/>
//这里添加组件
<HomeMiddleView/>
</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,ListView} from 'react-native';
var Dimensions =require('Dimensions')
var {width, height} = Dimensions.get('window');
import HomeMiddleCommonView from './HomeMiddleCommonView'
export default class HomeMiddleView extends Component<Props> {
constructor(Props) {
super(Props);
this.state={
rightData:[{"title":"天天特价","subTitle":"特惠不打烊",
img1:require('../../res/images/tttj.png'),
rightImage:require('../../res/images/tttj.png'),
"titleColor":"orange"},
{"title":"一元吃","subTitle":"一元吃美食",
img1:require('../../res/images/tttj.png')
,rightImage:require('../../res/images/yyms.png'),
"titleColor":"red"}]
}
}
render() {
return (
<View style={styles.containerSty}>
{/*左边*/}
{this.renderLeftView()}
{/*右边*/}
//用<View/>包裹,可以设置为竖轴
<View>
{this.renderRightView()}
</View>
</View>
);
}
renderRightView() {
var itemArr=[]
for (var i = 0; i <this.state.rightData.length; i++) {
var data =this.state.rightData[i];
itemArr.push(<HomeMiddleCommonView
title={data.title}
subTitle={data.subTitle}
rightIcon={data.rightImage}
titleColor={data.titleColor}
key={i}
/>)
}
return itemArr;
}
renderLeftView() {
var data ={img1:require('../../res/images/mdqg.png'),img2:require('../../res/images/yyms.png')}
return (<View style={styles.leftViewStyle}>
<Image source={data.img1} style={styles.leftImageStyle} />
<Image source={data.img2} style={{ width: 44,
height: 30,}}/>
<Text style={{color:'gray'}}>探路者烤鱼</Text>
<Text style={{color:'blue',fontSize:10}}>9.5</Text>
</View>)
}
}
const styles = StyleSheet.create({
leftImageStyle:{
width: 129,
height: 42,
marginTop: 10
},
leftViewStyle:{
width:width*0.5,
height:119,
backgroundColor:'white',
marginRight:1,
//交叉轴居中
alignItems:'center',
},
containerSty:{
marginTop:10,
flexDirection: "row",
}
});
/**
* 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,Image, View} from 'react-native';
var Demensions = require('Dimensions');
//初始化宽高
var {width, height} = Demensions.get('window');
export default class HomeMiddleCommonView extends Component<Props> {
static defaultProps={
title:"",
subTitle:"",
rightIcon:undefined,
titleColor:"",
}
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.containerStyle}>
<View>
<Text style={[{color:this.props.titleColor},styles.titleStyle]}>{this.props.title}</Text>
<Text style={styles.subTitltStyle}>{this.props.subTitle}</Text>
</View>
<Image source={this.props.rightIcon} style={{width:64,height:43}}/>
</View>
);
}
}
const styles = StyleSheet.create({
containerStyle: {
//1是分割线
width:width*0.5-1,
flex: 1,
justifyContent: 'space-around',
alignItems: 'center',
backgroundColor: 'white',
flexDirection:"row",
//分割线
borderBottomColor:'gray',
borderBottomWidth:0.2,
},
subTitltStyle:{
color:'gray'
}
});
第二:FlagList
ListView有缺点
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow
* @lint-ignore-every XPLATJSCOPYRIGHT1
*/
import React, {Component} from 'react';
import {Platform,RefreshControl,ActivityIndicator, StyleSheet, Text,FlatList, View} from 'react-native';
const CITY_NAMES = ['北京', '上海', '广州', '深圳', '杭州', '苏州', '成都', '武汉', '郑州', '洛阳', '厦门', '青岛', '拉萨'];
export default class Find extends Component<Props> {
constructor(props) {
super(props);
this.state={
isLoading:false,
dataArray: CITY_NAMES,
responce:""
}
}
loadData(refreshing) {
console.log("----2----->"+refreshing);
if (refreshing) {
this.setState({isLoading: true})
}
// 模拟网络请求
setTimeout(()=>{
let dataArray = [];
//下拉刷新
if (refreshing) {
for (let i = this.state.dataArray.length - 1; i >= 0; i--) {
dataArray.push(this.state.dataArray[i]);
}
//上拉加载
}else {
dataArray = this.state.dataArray.concat(CITY_NAMES);
}
this.setState({
//网络请求完成
dataArray:dataArray,
})
this.setState({
//网络请求完成
isLoading:false
})
},2000)
}
genIndicator(){
return <View style={styles.indicatorContainer}>
<ActivityIndicator
style={styles.indicator}
size={'large'}
color={'red'}
animating={true}
/>
<Text>正在加载更多</Text>
</View>
}
_renderItem(data) {
return (<View style={styles.item}>
<Text style={styles.text}>
{data.item}
</Text>
</View>)
}
render() {
return (
<View style={styles.containerStyle}>
<Text>{this.state.responce}</Text>
<FlatList
data={this.state.dataArray}
//1,从data中挨个取出数据并渲染到列表中。类似于ListView的renderRow
//2,接收一个函数
//3,data要放到state里面
renderItem={(data) => this._renderItem(data)}
refreshing={this.state.isLoading}
//用户触动刷新
onRefresh={()=>{
console.log("---1------>"+this.state.isLoading);
this.loadData(true);
}}
//下拉刷新,返回<RefreshControl/>控件
refreshControl={
<RefreshControl
title={'loading'}
color={['red']}
tintColor={'orange'}
titleColor={'red'}
//往下拉的时候产生回调函数,回调到该函数里
/>
}
//上拉加载更多
ListFooterComponent={()=>this.genIndicator()}
//一旦到达底部,就刷新
onEndReached={()=>{
//可以不传值
this.loadData()
}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
text:{
color: 'white',
fontSize: 20,
},
item: {
backgroundColor: '#169',
height: 200,
marginBottom: 15,
alignItems: 'center',
justifyContent: 'center'
},
containerStyle: {
flex:1
},
});
第三:网络请求
fetch( `http://192.168.1.109:8090/weixinapp/studentinfo/reactlist`)
//1,then里面传递的是一个接口
//2,第一个then返回的是responce.json(),并将responce.json()作为参数返回给第二个then。
//3.then的参数是我们得到的针对本次请求的对象
//4,在RN里面json字符串就是一个对象
//5,拿到response之后呢就可以解析数据
.then((responce)=>responce.json()).then(responceJson=>{
this.setState({
responce:responceJson[0].mainTitle
})
}).done()
上面的代码与android中的这个代码比较类似
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
fetch(url)相当于okHttpClient.newCall(request).enqueue(new Callback() ;
onResponse相当于then;
fetch是全局变量,不需要任何引用