一个简单的ReactNative demo
2016-08-24 本文已影响4017人
夏洛克的喵
本人非前端,请轻喷
ReactNative版本:0.31
github:https://github.com/X-FAN/reactnativelearn
代码做了一些简单的注释,下面是源码
import React, {
Component
}
from 'react';
import {
AppRegistry,
Navigator,
ToastAndroid
}
from 'react-native';
import LoginComponet from './LoginComponet'
class AwesomeProject extends Component {
render() {
let defaultName = 'LoginComponet';
let defaultComponent = LoginComponet;
return (
<Navigator
initialRoute={{name: defaultName, component: defaultComponent}}
configureScene={(route) => {//定义跳转的方式,禁用手势拖动跳转
return {...Navigator.SceneConfigs.FadeAndroid, gestures: false};
}}
renderScene={(route, navigator) => {
let Component = route.component;
//路由的参数和navigator都传入到跳转的component内
return <Component {...route} navigator={navigator}/>
}}/>
//{...route} 将route的每个属性都传过去
);
}
}
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
import React, {
Component,
PropTypes
} from 'react';
import {
View,
TextInput,
StyleSheet,
TouchableNativeFeedback,
Text,
TouchableHighlight,
Navigator
} from 'react-native'
import AndroidGankComponent from './AndroidGankComponent'
class LoginComponet extends Component {
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
};
}
check(username, password) {
if (username.length == 0) {
ToastAndroid.show('请填写账号', ToastAndroid.LONG)
} else if (password.length == 0) {
ToastAndroid.show('请填写密码', ToastAndroid.LONG);
} else {
this.props.navigator.push({//跳转到AndroidGankComponent
name: 'AndroidGankComponent',
component: AndroidGankComponent,
})
}
}
render() {
return (
<View style={{margin: 10, flex: 1, flexDirection: 'column'}}>
<TextInput style={[styles.basic, {marginTop: 30}] }
placeholderTextColor='#757575'
placeholder='请输入账号'
onChangeText={(text)=> {
this.setState({username: text});
}}/>
<TextInput style={styles.basic}
placeholderTextColor='#757575'
placeholder='请输入密码'
onChangeText={(text)=> {
this.setState({password: text});
}}/>
<TouchableNativeFeedback
background={TouchableNativeFeedback.SelectableBackground()}
onPress={()=>this.check(this.state.username, this.state.password)}
>
<View style={{borderRadius: 10, backgroundColor: '#0097A7', marginTop: 30}}>
<Text style={styles.text}>登录</Text>
</View>
</TouchableNativeFeedback>
</View>
);
}
}
/**
* 样式封装
*/
const styles = StyleSheet.create({
basic: {
padding: 10
},
text: {
fontSize: 18,
color: '#FFFFFF',
margin: 10,
textAlign: 'center'
}
});
export default LoginComponet;
import React, {
Component
} from 'react'
import {
View,
Text,
ListView,
ToastAndroid,
StyleSheet,
BackAndroid,
Image,
TouchableHighlight,
TouchableWithoutFeedback,
ActivityIndicator,
RefreshControl
} from 'react-native';
import WebViewComponet from './WebViewComponet';
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
class AndroidGankComponent extends Component {
constructor(props) {
super(props);
this.state = {
isRefreshing: false,
dataSource: ds,
};
}
componentWillMount() {
this.genRows();
BackAndroid.addEventListener('hardwareBackPress', ()=>this.goBack());//监听安卓回退按钮
}
render() {
if (this.state.dataSource.getRowCount() === 0) {//没有数据时展示'加载视图'
return (
<View style={ {flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center'}}>
<ActivityIndicator
size='large'
color='#8BC34A'/>
</View>
);
} else {
return (
//标题栏
<View style={{flexDirection: 'column', flex: 1}}>
<View style={{flexDirection: 'row', backgroundColor: '#00BCD4', padding: 10}}>
<TouchableWithoutFeedback onPress={()=>this.goBack()}>
<Image style={{width: 30, height: 30}} source={require('./image/back.png') }/>
</TouchableWithoutFeedback>
<Text style={{fontSize: 20, color: "#FFFFFF"}}>安卓干货</Text>
</View>
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData)=>this.getRow(rowData)}
refreshControl={//下拉刷新的配置
<RefreshControl
refreshing={this.state.isRefreshing}
onRefresh={()=>this.onRefresh}//刷新触发的函数
colors={['#8BC34A']}
progressBackgroundColor="#ffffff"
/>
}>
</ListView>
</View>
);
}
}
/**
* 获取listview的数据源
*/
genRows() {
this.getAndroidGank();
}
/**
* 渲染listview的每行的内容
* @param rowData
* @returns {XML}
*/
getRow(rowData) {
return (
<TouchableWithoutFeedback onPress={()=>this.jumpToGank(rowData.url)}>
<View style={styles.container}>
<Text style={styles.text}>{'标题:' + rowData.desc}</Text>
<Text style={styles.subText}>{'推荐人:' + rowData.who}</Text>
</View>
</TouchableWithoutFeedback>
)
}
/**
* 展示具体干货内容
* @param url
*/
jumpToGank(url) {
this.props.navigator.push({
url: url,
name: 'WebViewComponet',
component: WebViewComponet
});
}
/**
* 网络请求获取安卓干货
*/
getAndroidGank() {
fetch('http://gank.io/api/data/Android/10/1')
.then((response)=> {
return response.json();
})
.then((responseJson)=> {
if (responseJson.results) {
this.setState({isRefreshing: false, dataSource: ds.cloneWithRows(responseJson.results)});//修改状态值,再次渲染
}
}).catch((error)=>console.error(error))
.done();
}
/**
* 回退
*/
goBack() {
const nav = this.props.navigator;
const routers = nav.getCurrentRoutes();
if (routers.length > 1) {
nav.pop();
return true;
}
return false;
}
/**
* 下拉刷新
*/
onRefresh() {
this.genRows();
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'column',
justifyContent: 'center',
padding: 10,
margin: 10,
backgroundColor: '#B2EBF2',
borderRadius: 5
},
text: {
fontSize: 18,
color: '#212121'
},
subText: {
fontSize: 18,
color: '#757575'
}
});
export default AndroidGankComponent;
import React, {
Component,
} from 'react';
import {
View,
WebView,
ToastAndroid,
TouchableWithoutFeedback,
Image,
Text
} from 'react-native';
class WebViewComponet extends Component {
render() {
return (
<View style={{flexDirection: 'column', flex: 1}}>
<View style={{flexDirection: 'row', backgroundColor: '#00BCD4', padding: 10}}>
<TouchableWithoutFeedback onPress={()=>this.goBack()}>
<Image style={{width: 30, height: 30}} source={require('./image/back.png') }/>
</TouchableWithoutFeedback>
<Text style={{fontSize: 20, color: "#FFFFFF"}}>安卓干货</Text>
</View>
<WebView
startInLoadingState={true}
javaScriptEnabled={true}
domStorageEnabled={true}
source={{uri: this.props.url}}/>//根据属性里传过来的url加载
</View>
);
};
/**
* 回退
*/
goBack() {
const nav = this.props.navigator;
const routers = nav.getCurrentRoutes();
if (routers.length > 1) {
nav.pop();
return true;
}
return false;
}
}
export default WebViewComponet;
2016.9.8:引入第三方开源库react-native-scrollable-tab-view
**2016.11.18 **更新界面设计
效果图参考:
http://es6.ruanyifeng.com
http://www.ruanyifeng.com/blog/2015/03/react.html
https://facebook.github.io/react-native/