如果感觉我写的不错,关注我,给个star哦!项目地址
如果遇到什么问题可以在评论区回复,或者加QQ群397885169讨论
前言
昨天终于把公司双十二的项目上线了,才有了时间写这第二篇文章,在上一篇中我们将项目的目录结构建好了,今天我们就来讲一下网络请求,首页布局和cell头部和尾部的布局。
网络
俗话说:兵马未动,粮草先行。子曰:”工欲善其事,必先利其器“。一款App如果没有数据,那只能是一个壳子,所以我们就先讲一下网络请求和请求封装。
在第一篇中我说了,做百思不得姐最重要的一点就是有接口,我在做之前搜到了易源提供了百思不得姐的接口,第一眼看到的时候是很惊喜的,但真的调用过就会发现,其中有好大的坑,让我放弃它最主要的一点就是,调用图片的时候,并没有提供图片的宽度和高度!!!在百思不得姐中是有长图,动图和普通图片之分的,如果没有返回图片的宽高,那图片的布局就只能定死,页面是很难看的,特别是长图的时候。
如果在我的项目中有些接口数据不清楚的话,也可以对着易源提供的百思不得姐接口来看一下接口详情。
最终的解决办法就是找到了iOS大神,小码哥老大李明杰曾讲过的百思不得姐的接口。
网络封装
因为是抓来的接口,所以我只封装了get请求的部分,以后可能会有页面用到post。
request.js
const Request = {
get:(url, successCallBack , failCallBack) =>{
console.log(url);
return fetch(url)
.then((response) => response.json())
.then((response) => {
successCallBack(response);
})
.catch ((error) => {
failCallBack(error);
});
}
};
module.exports = Request;
网络请求当然最好是把网址什么的拆出去啦!因为暂时只用到首页,其他页面就没有加在上面咯。
config.js
const Config = {
api:{
homeList:'http://api.budejie.com/api/api_open.php?a=list&c=data',
},
};
module.exports = Config;
首页
如果用过百思不得姐就会知道,它的首页是一个不可滚动的类新闻应用。但为了省事,我在这里使用了一个三方来实现了可以左右滚动的首页。
homeContainer.js
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity
} from 'react-native';
import NavBar from 'react-native-navbar';
import ScrollableTabView, {DefaultTabBar, ScrollableTabBar} from 'react-native-scrollable-tab-view';
import HomeList from './homeList';
export default class homeContainer extends Component {
constructor(props){
super(props);
this.state = {
typeArr : [
{'title':'全部', 'type':'1',},
{'title':'视频', 'type':'41',},
{'title':'图片', 'type':'10',},
{'title':'段子', 'type':'29',},
{'title':'声音 ', 'type':'31',},
],
}
}
render() {
let titleConfig = {
title: '百思不得姐',
style: {color:'red',fontSize:20,fontWeight:'600'}
};
return (
<View style={styles.container}>
<NavBar
title={titleConfig}
style={{height:44,borderBottomWidth:1,borderBottomColor:'#dddddd'}}
/>
<ScrollableTabView
renderTabBar={() => <ScrollableTabBar/>}
tabBarActiveTextColor='red'
tabBarInactiveTextColor='#rgb(67,67,67)'
tabBarBackgroundColor='#f7f7f7'
style={{height:10}}
>
{
this.state.typeArr.map((item, i) => {
return (
<HomeList key={i} tabLabel={item.title} type={item.type}
navigator={this.props.navigator} {...this.props}/>
)
})
}
</ScrollableTabView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
首页详情
首页的左右滚动效果已经实现了,那么就要开始展示具体内容了
homeList.js
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
ListView,
InteractionManager,
ActivityIndicator,
RefreshControl
} from 'react-native';
import Config from '../../common/config';
import Request from '../../common/request';
import ListItem from './component/listItem';
let cacheResults = {
items:[],
allPage:0,
maxId:'',
};
export default class homeList extends Component {
constructor(props){
super(props);
let dataSource = new ListView.DataSource({rowHasChanged:(r1,r2) => r1 !== r2});
this.state = {
dataSource : dataSource,
isRefreshing : false,
isLoad: false,
isLoadingMore:false,
maxId: '',
};
this.renderRow = this.renderRow.bind(this);
this.onRefresh = this.onRefresh.bind(this);
this.onEndReached = this.onEndReached.bind(this);
this.renderFooter = this.renderFooter.bind(this);
}
renderFooter(){
if (!this.isMore()){
console.log('1');
return (
<View style={styles.loadMoreStyle}>
<Text style={styles.loadMoreTextStyle} >没有更多数据了</Text>
</View>
)
}
if (!this.state.isLoadingMore){
return <View style={styles.loadMoreStyle} />
}
return(
<ActivityIndicator
style={styles.loadMoreStyle}
/>
)
}
// 服务器有没有更多数据
isMore(){
// 全部count等于整体count,那就说明结束了
return cacheResults.items.count !== 2000;
}
// 加载更多数据
onEndReached(){
if (!this.isMore() || this.state.isLoadingMore ){
return;
}
console.log(this.state.maxId);
this.loadData(this.state.maxId);
}
// 下拉刷新
onRefresh(){
console.log(this.state.maxId);
this.loadData(0);
}
// 跳转页面
pushPage(rowData){
let {navigator} = this.props;
if (navigator) {
InteractionManager.runAfterInteractions(()=> {
navigator.push({
component: NewsDetail,
passProps:{
link:rowData.link,
}
})
});
}
}
componentDidMount() {
this.loadData(0);
}
loadData(maxtime){
if (maxtime !== 0){
this.setState({
isLoadingMore:true
});
}else {
this.setState({
isRefreshing :true
});
}
Request.get(Config.api.homeList + '&type='+ this.props.type +'&maxtime=' + maxtime ,(data)=>{
console.log(data);
let items = cacheResults.items.slice();
let contentlist = data.list;
if (maxtime !== 0){
items = items.concat(contentlist);
cacheResults.items = items;
} else {
items = contentlist;
cacheResults.items = items;
}
cacheResults.allPage = data.info.page;
this.setState({
maxId:data.info.maxid
});
setTimeout(()=>{
if (maxtime !== 0){
this.setState({
dataSource: this.state.dataSource.cloneWithRows(items),
isRefreshing:false,
isLoad:true,
isLoadingMore:false,
});
} else {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(items),
isLoad :true,
isRefreshing:false,
isLoadingMore:false,
});
}
},0);
},(error)=>{
console.log(error);
});
}
renderRow(rowData){
return(
<ListItem itemData={rowData}/>
)
}
render() {
return (
<View style={styles.container}>
{
this.state.isLoad ?
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
enableEmptySections={true}
onEndReached={this.onEndReached}
onEndReachedThreshold={40}
renderFooter={this.renderFooter}
refreshControl={
<RefreshControl
refreshing={this.state.isRefreshing}
onRefresh={this.onRefresh}
/>
}
/>
:
<ActivityIndicator
style={styles.loadDataStyle}
/>
}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
loadDataStyle: {
marginVertical:20
},
loadMoreStyle:{
marginVertical:20
},
});
自定义Item
当前的页面中我只是简单的展示了文字,而真正的图片,头像等我都没有展示出来,接下来就是展示环节了。
导入组件
react-native-scrollable-tab-view
这个就是我们用来创建顶部滚动的控件啦!它还可以放在底部实现类似于安卓版微信那种的滚动tabBar;
吐槽
在列表页中,我将上拉刷新和下拉加载都放在了一起,并没有使用Redux。为什么呢?因为,我之前在上一个项目中做实验的时候发现,这种左右滚动的页面,如果用Actions来管理网络,页面的数组不好清空,我弄了大半天最后找了个折中的方式,将网络请求放在Actions里面,将数据获取又放回了List列表页里面,我感觉如果那样写真的是不如一个页面全都实现了,逻辑上也不是那么不清晰。
当然,我会在之后的一些页面中使用Redux,Redux并不是每个页面都用才好!
我在使用react-native-scrollable-tab-view
时想改变底部滚动条的颜色,发现调用它提供的方法竟然改不了!一起之下,我就杀进了这个库里面,直接改了部分源码。
总结
现在用的这个接口用起来是有一点问题的。我在上拉加载更多的时候卡住了好久。
如果在使用中遇到什么问题,欢迎私信和评论哦!
如果喜欢我的文章,关注我,给个star哦!