这里先从最近看ReactNative文档发现的expo说起,因为使用expo可以直接在ios或者安卓展示ReactNative的效果,门槛突然降低了许多,因此,突发奇想试试做native app。
首先可以按照ReactNative的GetStart配置完环境并完成一个hello world!
总体如果有node和npm的话就以下两步:
npm install -g create-react-native-app
create-react-native-app AwesomeProject cd AwesomeProject npm start
然后等出现一个二维码,用手机上的expo App扫码就行,ios和安卓都行哦!
再来上新闻代码,写在文件的app.js里,这里在IOS上做尝试。
先引入之后会用到一些的组件
import React, { Component, PropTypes } from 'react'; import { AppRegistry,RefreshControl,TouchableWithoutFeedback, WebView,ActivityIndicator ,ListView, Text, Image, View, StyleSheet, TextInput, Button, Alert, ScrollView, NavigatorIOS, TouchableHighlight, FlatList } from 'react-native';
第一个主组件,写了一个ios的导航条,内容在main组件里
export default class Test extends Component { constructor(props){ super(props); } render() { return ( <NavigatorIOS initialRoute={ { component: main, title: "头条", } } style={ { flex: 1 } } ref="navWorkspace" /> ) } }
main组件,主要用到了fetch来拉取新闻,在放入ListView组件内,
其中又加了RefreshControl组件来下拉刷新,ListView的onEndReached来控制上拉加载更多。这里有个疑问,用FlatList不能实现上拉加载更多?
class main extends Component { constructor(props) { super(props); this.state = { onEndStart: true, totalList:[], dataSource: null, page:2, refreshing:false, }; } fetchData(){ return fetch("http://api.dagoogle.cn/news/get-news?page=1").then((response)=>response.json()) } _onRefresh(){ this.setState({ refreshing:true }) this.fetchData().then((responseJson)=>{ var tmp=parseInt(responseJson.data[0].news_id)-parseInt(this.state.totalList[0].news_id) if(tmp!=0){ for(let i=tmp-1;i>=0;i--){ this.state.totalList.unshift(responseJson.data[i]) } } let ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); this.setState({ refreshing:false, dataSource:ds.cloneWithRows(this.state.totalList) }) }) } getnews(page){ return fetch("http://api.dagoogle.cn/news/get-news?page="+page) .then((response) => response.json()) .then((responseJson) => { let ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); for(let i in responseJson.data){ this.state.totalList.push(responseJson.data[i]) } this.setState({ dataSource: ds.cloneWithRows(this.state.totalList), onEndStart: false }) }) } componentDidMount() { return fetch("http://api.dagoogle.cn/news/get-news?page=1") .then((response) => response.json()) .then((responseJson) => { let ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); this.setState({ totalList: responseJson.data, dataSource: ds.cloneWithRows(responseJson.data), onEndStart: false }) }) } toend(){ if(!this.state.onEndStart){ this.getnews(this.state.page); this.setState({ page:this.state.page+1 }) } } goTo(key){ this.props.navigator.push({ component: Detail, title: '详情', rightButtonTitle: '收藏', passProps: { title: this.state.totalList[key].title,content:this.state.totalList[key].content,source:this.state.totalList[key].source}, onRightButtonPress: function() {alert(1)} }); } render() { if (this.state.onEndStart) { return ( <ActivityIndicator style={ {flex:1,alignItems:'center',height:80} } animating={true}/> ) } return ( <ListView refreshControl={ <RefreshControl refreshing={this.state.refreshing} onRefresh={this._onRefresh.bind(this)} /> } style={ {marginTop:65} } dataSource={this.state.dataSource} renderRow={(item,sectionId,rowId) => <TouchableWithoutFeedback onPress={this.goTo.bind(this,rowId)}> <View style={styles.list_item}> <Text style={styles.list_item_font}> {item.title} </Text> <Image source={ { uri: item.top_image } } style={styles.image}/> </View> </TouchableWithoutFeedback> } onEndReachedThreshold={150} onEndReached={this.toend.bind(this)} /> ) } }
之后点击新闻跳转到详情页。下面是详情页的组件
class Detail extends Component{ constructor(props){ super(props) } render(){ var html="<h3 style='margin-bottom:0'>"+this.props.title+"</h3>"+"<div style='color:gray;margin-bottom:-15;'>"+this.props.source+"</div>"+this.props.content; return( <View style={ {flex:1} }> <WebView source={ {html:html} }/> </View> ) } }
样式的话写在最后StyleSheet组件中,在上面的组件内可以直接用style={styles.xxx}调用样式。
const styles = StyleSheet.create({ flex: { flex: 1, }, list_item1: { marginLeft: 10, marginRight: 10, borderBottomWidth: 1, borderBottomColor: '#ddd', flex: 1, flexDirection: 'row', alignItems: 'center', }, list_item: { height:80, marginLeft: 10, marginRight: 10, borderBottomWidth: 1, borderBottomColor: '#ddd', flex: 1, flexDirection: 'row', alignItems: 'center', }, list_item_font: { marginRight: 1, flex: 3, fontSize: 16, }, image: { flex: 1, width: 60, height: 60, } });
然后就可以
npm start
在手机expo里看到效果咯。
效果展示:
版权声明:本文为原创文章,转载请注明出处和作者,不得用于商业用途,请遵守
CC BY-NC-SA 4.0协议。
赞赏一下