先上效果圖:下拉刷新,上拉加載更多效果不好截圖啊
列表頁.png
詳情頁面.png
接口返回.png
所用到的控件:
A.FlatList 實現(xiàn)列表展示粘室,上拉加載,下拉刷新效果
B.react-native-router-flux 實現(xiàn)點擊列表的item,跳轉(zhuǎn)到詳情頁卜范,并傳值
C.react-native 自帶的webview展示網(wǎng)頁界面衔统。
參考:上拉加載,跳轉(zhuǎn)簡單實用,webview
感謝文章的作者。
下面上代碼:
1.在index.js定義
import { AppRegistry } from 'react-native';
import MyList from "./demo/listtest";//這里根據(jù)自己的目錄導入
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.創(chuàng)建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;//總的頁數(shù)
let itemNo=0;//item的個數(shù)
export default class LoadMoreDemo extends Component {
constructor(props) {
super(props);
this.state = {
page:1,
isLoading: true,
//網(wǎng)絡請求狀態(tài)
error: false,
errorInfo: "",
dataArray: [],
showFoot:0, // 控制foot犬缨, 0:隱藏footer 1:已加載完成,沒有更多數(shù)據(jù) 2 :顯示加載中
isRefreshing:false,//下拉控制
}
}
//網(wǎng)絡請求——獲取數(shù)據(jù)
fetchData() {
//這個是js的訪問網(wǎng)絡的方法
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 數(shù)據(jù)并存在data數(shù)組中
let dataBlob = [];//這是創(chuàng)建該數(shù)組,目的放存在key值的數(shù)據(jù)棉浸,就不會報黃燈了
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底部顯示沒有更多數(shù)據(jù)了
}
this.setState({
//復制數(shù)據(jù)源
// 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() {
//請求數(shù)據(jù)
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})//跳轉(zhuǎn)并傳值
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();
}
//加載數(shù)據(jù)
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,}}>
沒有更多數(shù)據(jù)了
</Text>
</View>
);
} else if(this.state.showFoot === 2) {
return (
<View style={styles.footer}>
<ActivityIndicator />
<Text>正在加載更多數(shù)據(jù)...</Text>
</View>
);
} else if(this.state.showFoot === 0){
return (
<View style={styles.footer}>
<Text></Text>
</View>
);
}
}
_onEndReached(){
//如果是正在加載中或沒有更多數(shù)據(jù)了迷郑,則返回
if(this.state.showFoot != 0 ){
return ;
}
//如果當前頁大于或等于總頁數(shù)枝恋,那就是到最后一頁了,返回
if((this.state.page!=1) && (this.state.page>=totalPage)){
return;
} else {
this.state.page++;
}
//底部顯示正在加載更多數(shù)據(jù)
this.setState({showFoot:2});
//獲取數(shù)據(jù)嗡害,在componentDidMount()已經(jīng)請求過數(shù)據(jù)了
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,
}
});
代碼不多但是在使用過程中還是遇到一些問題焚碌,后面都解決了。最后感謝分享的作者霸妹。