先上效果图:下拉刷新,上拉加载更多效果不好截图啊
所用到的控件:
A.FlatList 实现列表展示,上拉加载,下拉刷新效果
B.react-native-router-flux 实现点击列表的item,跳转到详情页,并传值
C.react-native 自带的webview展示网页界面。
参考:上拉加载,跳转简单实用,webview
感谢文章的作者。
下面上代码:
1.在index.js定义
import { AppRegistry } from 'react-native';
import MyList from "./demo/listtest";//这里根据自己的目录导入
import React from "react";
import NewsDetails from "./reactjs/newsdetials";
import {Router, Scene} from "react-native-router-flux";
class MyRouter extends React.Component {
render() {
return <Router>
<Scene key="root">
<Scene key="list" component={MyList} title="星APP" initial={true} />
<Scene key="news" component={NewsDetails} title="详情页"/>
</Scene>
</Router>
}
}
AppRegistry.registerComponent('HelloRN', () => MyRouter);
//initial={true}默认显示
2.创建listtest.js文件,展示列表
import React, {Component} from "react";
import {
ActivityIndicator,
FlatList,
RefreshControl,
StyleSheet,
Text,
TouchableNativeFeedback, TouchableOpacity,
View
} from "react-native";
import { Actions } from 'react-native-router-flux';
const REQUEST_URL = 'http://gank.io/api/data/Android/10/';
let totalPage=5;//总的页数
let itemNo=0;//item的个数
export default class LoadMoreDemo extends Component {
constructor(props) {
super(props);
this.state = {
page:1,
isLoading: true,
//网络请求状态
error: false,
errorInfo: "",
dataArray: [],
showFoot:0, // 控制foot, 0:隐藏footer 1:已加载完成,没有更多数据 2 :显示加载中
isRefreshing:false,//下拉控制
}
}
//网络请求——获取数据
fetchData() {
//这个是js的访问网络的方法
console.log(REQUEST_URL+this.state.page)
fetch(REQUEST_URL+this.state.page,{
method: 'GET',
})
.then((response) => response.json())
.then((responseData) => {
let data = responseData.results;//获取json 数据并存在data数组中
let dataBlob = [];//这是创建该数组,目的放存在key值的数据,就不会报黄灯了
let i = itemNo;
data.map(function (item) {
dataBlob.push({
key: i,
desc: item.desc,
time: item.createdAt,
who:item.who
, url:item.url
})
i++;
});
itemNo = i;
let foot = 0;
if(this.state.page>=totalPage){
foot = 1;//listView底部显示没有更多数据了
}
this.setState({
//复制数据源
// dataArray:this.state.dataArray.concat( responseData.results),
dataArray:this.state.dataArray.concat( dataBlob),
isLoading: false,
showFoot:foot,
isRefreshing:false,
});
data = null;//重置为空
dataBlob = null;
})
.catch((error) => {
this.setState({
error: true,
errorInfo: error
})
})
.done();
}
componentDidMount() {
//请求数据
this.fetchData( );
}
shouldComponentUpdate() {
return true
}
handleRefresh = () => {
this.setState({
page:1,
isRefreshing:true,//tag,下拉刷新中,加载完全,就设置成flase
dataArray:[]
});
this.fetchData()
}
itemClick = () => {
alert("ff")
{Actions.news}
}
//加载等待页
renderLoadingView() {
return (
<View style={styles.container}>
<ActivityIndicator
animating={true}
color='blue'
size="large"
/>
</View>
);
}
_keyExtractor = (item, index) => index;
//加载失败view
renderErrorView() {
return (
<View style={styles.container}>
<Text>
{this.state.errorInfo}
</Text>
</View>
);
}
//返回itemView
_renderItemView({item}) {
//onPress={gotoDetails()}
const gotoDetails=()=>Actions.news({'url':item.url})//跳转并传值
return (
// <TouchableNativeFeedback onPress={() => {Actions.news({'url':item.url})}} >////切记不能带()不能写成gotoDetails()
<TouchableNativeFeedback onPress={gotoDetails}>
<View >
<Text style={styles.title}>{item.desc}</Text>
<Text style={styles.content}>时间: {item.time}</Text>
<Text style={styles.content}>作者: {item.who}</Text>
</View>
</TouchableNativeFeedback >
);
}
renderData() {
return (
<FlatList
data={this.state.dataArray}
renderItem={this._renderItemView}
ListFooterComponent={this._renderFooter.bind(this)}
onEndReached={this._onEndReached.bind(this)}
onEndReachedThreshold={0.1}
ItemSeparatorComponent={this._separator}
keyExtractor={this._keyExtractor}
//为刷新设置颜色
refreshControl={
<RefreshControl
refreshing={this.state.isRefreshing}
onRefresh={this.handleRefresh.bind(this)}//因为涉及到this.state
colors={['#ff0000', '#00ff00','#0000ff','#3ad564']}
progressBackgroundColor="#ffffff"
/>
}
/>
);
}
render() {
//第一次加载等待的view
if (this.state.isLoading && !this.state.error) {
return this.renderLoadingView();
} else if (this.state.error) {
//请求失败view
return this.renderErrorView();
}
//加载数据
return this.renderData();
}
_separator(){
return <View style={{height:1,backgroundColor:'#999999'}}/>;
}
_renderFooter(){
if (this.state.showFoot === 1) {
return (
<View style={{height:30,alignItems:'center',justifyContent:'flex-start',}}>
<Text style={{color:'#999999',fontSize:14,marginTop:5,marginBottom:5,}}>
没有更多数据了
</Text>
</View>
);
} else if(this.state.showFoot === 2) {
return (
<View style={styles.footer}>
<ActivityIndicator />
<Text>正在加载更多数据...</Text>
</View>
);
} else if(this.state.showFoot === 0){
return (
<View style={styles.footer}>
<Text></Text>
</View>
);
}
}
_onEndReached(){
//如果是正在加载中或没有更多数据了,则返回
if(this.state.showFoot != 0 ){
return ;
}
//如果当前页大于或等于总页数,那就是到最后一页了,返回
if((this.state.page!=1) && (this.state.page>=totalPage)){
return;
} else {
this.state.page++;
}
//底部显示正在加载更多数据
this.setState({showFoot:2});
//获取数据,在componentDidMount()已经请求过数据了
if (this.state.page>1)
{
this.fetchData();
}
}
}
const styles = StyleSheet.create({
container: {
padding:10,
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
title: {
marginTop:8,
marginLeft:8,
marginRight:8,
fontSize: 15,
color: '#ffa700',
},
footer:{
flexDirection:'row',
height:24,
justifyContent:'center',
alignItems:'center',
marginBottom:10,
},
content: {
marginBottom:8,
marginLeft:8,
marginRight:8,
fontSize: 14,
color: 'black',
}
});
3.webview详情页面
import React, {Component} from 'react';
import {
StyleSheet,
Dimensions,
View,
WebView
} from 'react-native';
//获取设备的宽度和高度
var {
height: deviceHeight,
width: deviceWidth
} = Dimensions.get('window');
export default class NewsDetails extends Component {
//渲染
render() {
return (
<View style={styles.container}>
<WebView bounces={false}
scalesPageToFit={true}
source={{uri:this.props.url}}
style={{width:deviceWidth, height:deviceHeight}}>
</WebView>
</View>
);
}
}
//样式定义
const styles = StyleSheet.create({
container: {
flex: 1,
}
});
代码不多但是在使用过程中还是遇到一些问题,后面都解决了。最后感谢分享的作者。