React Native学习记录
参考资料:
react native中文网
http://reactnative.cn/docs/0.31/getting-started.html
react native专题博客
http://www.lcode.org/react-native/
- 使用 :
- 搭建开发环境(参照官网)
- 开发工具(VS Code + vscode-react-native插件)
创建项目 (命令)
- react-native init **项目名
- cd **项目名
- 运行 react-native run-android
- 手动运行 cd **项目名
我的目录:
参照官网开始写列子
主要实现的功能如下:
Props (属性)
组件在创建时就可以使用各种参数来进行定制。用于定制的这些参数就称为Props(属性)。
比如给Image设置图片资源的时候,source 就是一个属性;自定义的组件也可以使用props。
通过在不同的场景使用不同的属性定制,可以尽量提高自定义组件的复用范畴。只需在render函数中引用this.props,然后按需处理即可。
比如下边的代码: 实现简单的Text,Image的显示和属性的调用,以及自定义的属性的使用;
class PropsTest extends React.Component {
// 构造
constructor(props) {
super(props);
// 初始状态
this.navigator = this.props.navigator;
}
render(){
let pic = {
uri: 'http://upload.ct.youth.cn/2015/0707/1436200566521.jpg'
};
//省略其他图片
return (
<View style={styles.viewStyle}>
<ToolBar navigator={this.props.navigator} title={'Props(属性)'}/>
<Text style={styles.texrStyle}>滨崎步</Text>
<Image source= {pic} style={{width:400 ,height: 240 }}></Image>
<Text style={styles.texrStyle}>自定义2张排列</Text>
<Greeting2 imageUrl1={pic1} imageUrl2={pic2} />
<Text style={styles.texrStyle}>自定义3张排列</Text>
<Greeting3 imageUrl3={pic3} imageUrl4={pic4} imageUrl5={pic5} />
</View>
);
}
}
class Greeting2 extends React.Component {
render(){
return (
<View style={styles.greetingView}>
<Image source= {this.props.imageUrl1} style={{width: 160, height: 80}}></Image>
<Image source= {this.props.imageUrl2} style={{width: 160, height: 80}}></Image>
</View>
);
}
}
class Greeting3 extends React.Component {
render(){
return (
<View style={styles.greetingView}>
<Image source= {this.props.imageUrl3} style={{width: 100, height: 80}}></Image>
<Image source= {this.props.imageUrl4} style={{width: 100, height: 80}}></Image>
<Image source= {this.props.imageUrl5} style={{width: 100, height: 80}}></Image>
</View>
);
}
}
运行效果如下:
State(状态)
使用State控制需要改变的数据
实现一个点击按钮改变图片和文字的代码,再次点击再次改变.使用State控制showText,通过点击事件根据showText的值设置空间的信息.
class StateTest extends React.Component {
constructor(props) {
super(props);
this.navigator = this.props.navigator;
this.state = {showText : true};
}
render(){
let textContent = this.state.showText ? '滨崎步' : '宇多田光';
var url = this.state.showText ? 'http://upload.ct.youth.cn/2015/0707/1436200566521.jpg' : 'http://i5.qhimg.com/t01d8897aa3b7010d89.jpg';
let imageUri = {
uri: url
}
return(
<View style={styles.viewStyle}>
<ToolBar navigator={this.props.navigator} title={'State(状态)'}/>
<Text style={styles.texrStyle}>{textContent}</Text>
<Image source={imageUri} style={{width:400 ,height: 240 }}></Image>
<TouchableHighlight style={styles.touchAbleBg} >
<Text style={[styles.textColor,{fontSize:18}]} onPress={() => this._setStateView()}>
改变文字和图片
</Text>
</TouchableHighlight>
</View>
);
}
_setStateView(){
if(this.state.showText){
this.setState({showText: false });
}else{
this.setState({showText: true });
}
}
}
运行效果如下:
样式
关于样式的设置在代码页面基本都会用到一些,参照网
处理文本输入
TextInput是一个允许用户输入文本的基础组件。它有一个名为onChangeText的属性,此属性接受一个函数,而此函数会在文本变化时被调用。另外还有一个名为onSubmitEditing的属性,会在文本被提交后(用户按下软键盘上的提交键)调用。
我们实现的是根据输入的文字,在Text控件上显示输入的内容,代码下:
class InputTest extends React.Component {
constructor(props){
super(props);
this.state = {text:''};
}
render(){
return(
<View>
<ToolBar navigator={this.props.navigator} title={'TextInput(文本输入)'}/>
<TextInput
style={[{height: 40} , {padding: 10}]}
placeholder="这是输入提示"
onChangeText={(text) => this.setState({text})}
/>
<Text style={{padding: 10, fontSize: 42}}>
{this.state.text}
</Text>
</View>
);
}
}
效果就不展示了...
ScrollView滚动视图
关于滚动视图和安卓用法区别不大
这里有一个坑需要注意,就是在view嵌套的时候会出现不滚动的情况, 这里的话根布局的view 需要设置flex: 1才可以(类似安卓的权重属性).同样适用于listview布局.
先看代码
class ScrollViewRe extends React.Component {
render(){
let imageUrl = {
uri: 'http://i5.qhimg.com/t01d8897aa3b7010d89.jpg'
}
return(
<ScrollView>
<Text style={{fontSize:20}}>滚动视图展示</Text>
<Image source={imageUrl} style={styles.imageStyle}/>
<Image source={imageUrl} style={styles.imageStyle}/>
<Image source={imageUrl} style={styles.imageStyle}/>
<Image source={imageUrl} style={styles.imageStyle}/>
</ScrollView>
);
}
}
const styles = StyleSheet.create ({
viewStyle: {
flex: 1, //必须设置 ,否则不能滚动
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center'
},
imageStyle: {
width: 240,
height: 400
}
});
运行效果如下:
ListView 列表
这个效果就是列表, 有两个属性必须设置的 (dataSource和renderRow ). 一个时列表数据,一个时渲染的item
这里只是展示,没有实现更多功能, 后续实现更新和加载的功能;
class ListViewTest extends React.Component {
constructor(props){
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
var data = [20];
for (var index = 0; index < 20; index++) {
data[index] = 'TiaoPi' + index;
}
this.state = {
dataSource: ds.cloneWithRows(data)
}
}
_listItem(textData){
let imageUrl = {
uri: 'http://i5.qhimg.com/t01d8897aa3b7010d89.jpg'
}
return(
<View style={{flexDirection: 'row'}} >
<Image source={imageUrl} style={styles.imageStyle}></Image>
<Text>{textData}</Text>
</View>
);
}
render(){
return(
<View style={styles.viewStyle}>
<ToolBar navigator={this.props.navigator} title={'ListView(列表)'}/>
<ListView
dataSource={this.state.dataSource}
renderRow={this._listItem.bind(this)}
/>
</View>
);
}
}
效果如下:
ViewPager (使用开源项目实现)
react-native-swiper (https://github.com/leecade/react-native-swiper)
跟安卓viewpager类似 下边只是简单实现效果,后续继续学习
import Swiper from 'react-native-swiper';
class ViewPagerTest extends React.Component {
render(){
let pic3 = {
uri: 'http://img0.ph.126.net/V946kkk3daLMuEuHNDPJAQ==/732679364477853939.png'
};
let pic4 = {
uri: 'http://i5.qhimg.com/t01d8897aa3b7010d89.jpg'
};
let pic5 = {
uri: 'http://www.qzhxw.com/d/file/p/0905/69ad0d2bb46f815a9550ad20c07494b4.jpg'
};
return(
<View style={styles.viewStyle}>
<ToolBar navigator={this.props.navigator} title={'ViewPager(开源控件)'}/>
<Swiper style={styles.wrapper} showsButtons={false}>
<View style={styles.slide1}>
<Image source={pic3} style={styles.imageStyle}></Image>
<Text style={styles.text}>第1张</Text>
</View>
<View style={styles.slide2}>
<Image source={pic4} style={styles.imageStyle}></Image>
<Text style={styles.text}>第2张</Text>
</View>
<View style={styles.slide3}>
<Image source={pic5} style={styles.imageStyle}></Image>
<Text style={styles.text}>第3张</Text>
</View>
</Swiper>
</View>
);
}
}
效果如下 :
ListView上下拉刷新
基于RN提供的下拉刷新组件(refreshControl)和ListView的onEndReached方法实现
var myData = [];
class PullRefreshTest extends React.Component{
constructor (props){
super(props);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
for (var index = 0; index < 20; index++) {
myData.push('TiaoPi' + index);
}
this.state = ({
dataSource:ds.cloneWithRows(myData),isRefreshing : false
});
}
componentWillMount() {
this._genRows();
}
render(){
return(
<View style={styles.viewStyle}>
<ToolBar navigator={this.props.navigator} title={'PullRefreshListView'}/>
<ListView
enableEmptySections={true}
dataSource={this.state.dataSource}
renderRow={this._listItem.bind(this)}
onEndReached={this._toEnd.bind(this)}
onEndReachedThreshold={0}
refreshControl={
<RefreshControl
refreshing={this.state.isRefreshing}
onRefresh={this._onRefresh.bind(this)}
tintColor="#ff0000"
title="Loading..."
titleColor="#00ff00"
colors={['#ff0000', '#00ff00', '#0000ff']}
progressBackgroundColor="#ffff00"
/>}
/>
</View>
);
}
_listItem(textData){
let imageUrl = {
uri: 'http://i5.qhimg.com/t01d8897aa3b7010d89.jpg'
}
return(
<View style={{flexDirection: 'row'}} >
<Image source={imageUrl} style={styles.imageStyle}></Image>
<Text style={{fontSize:20}}>{textData}</Text>
</View>
);
}
_onRefresh(){
this.setState({isRefreshing: true});
myData = [];
for (var index = 0; index < 5; index++) {
myData.push('刷新后的TiaoPi' + index);
}
this.setState({
isRefreshing: false,
dataSource: this.state.dataSource.cloneWithRows(myData),
});
}
_refreshData(){
for (var index = 0; index < 10; index++) {
myData.push('TiaoPi' + index);
}
this._setDataSource(myData);
}
_toEnd(){
this._genRows();
}
_setDataSource(data){
this.setState({
dataSource: this.state.dataSource.cloneWithRows(data),
});
}
_genRows(){
for (var index = 0; index < 10; index++) {
myData.push('TiaoPi' + index);
}
this._setDataSource(myData);
}
}
侧滑菜单实现
DrawerLayoutAndroid 实现侧滑菜单
class DrawerLayoutTest extends React.Component {
render(){
let pic3 = {
uri: 'http://img0.ph.126.net/V946kkk3daLMuEuHNDPJAQ==/732679364477853939.png'
};
return (
<DrawerLayoutAndroid
ref='MyDrawerLayout'
drawerWidth={300}
drawerPosition={DrawerLayoutAndroid.positions.Left}
renderNavigationView={() => <DrawerView />}
>
<View>
<ToolBar navigator={this.props.navigator} title={'侧滑菜单展示'}/>
<View style={{flex: 1, alignItems: 'center'}}>
<Text style={{fontSize: 20}}>这是页面</Text>
<Image source={pic3} style={{width: 240,height: 320}}></Image>
<TouchableHighlight style={styles.touchAbleBg} onPress={() => this._drawerLayoutClick()}>
<Text style={[styles.textColor,{fontSize:18}]}>
菜单
</Text>
</TouchableHighlight>
</View>
</View>
</DrawerLayoutAndroid>
);
}
_drawerLayoutClick(){
this.refs.MyDrawerLayout.openDrawer();
}
}
class DrawerView extends React.Component {
render(){
let pic3 = {
uri: 'http://img0.ph.126.net/V946kkk3daLMuEuHNDPJAQ==/732679364477853939.png'
};
return(
<View style={{flex: 1, alignItems: 'center'}}>
<Image source={pic3} style={{width: 300,height: 400}}></Image>
<Text style={{fontSize: 20}}>这是菜单</Text>
</View>
);
}
}
拉风出游首页
先看代码 : 只显示实现代码, 样式的代码忽略了
class LafengHome extends React.Component {
render(){
return (
<View style={{flex: 1}}>
<ToolBar navigator={this.props.navigator} title={'拉丰出游'}/>
<ScrollView>
<HeadViewPager />
<Image source={require('./img/home_img_lvbao.png')} style={styles.centerImageStyle}></Image>
<Image source={require('./img/top_item.png')} style={styles.centerImageStyle2}></Image>
<HomeListView />
</ScrollView>
</View>
);
}
}
class HomeListView extends React.Component {
constructor(props){
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
var datas = [{title: '游艇', content: '游艇业务内容'},
{title: '飞机', content: '飞机业务介绍'},
{title: '豪车', content: '豪车业务介绍'}]
this.state = {
dataSource: ds.cloneWithRows(datas)
}
}
render(){
return(
<ListView
dataSource={this.state.dataSource}
renderRow={this._listItem.bind(this)}
/>
);
}
_listItem(datas){
let imageUrl = {
uri: 'http://img0.ph.126.net/V946kkk3daLMuEuHNDPJAQ==/732679364477853939.png'
}
return(
<View style={{flexDirection: 'row'}} >
<Image source={imageUrl} style={styles.imageBg}>
<View style={styles.viewBg}>
<Text style={styles.itemText1}>{datas.title}</Text>
<Text style={styles.itemText2}>{datas.content}</Text>
</View>
</Image>
</View>
);
}
}
class HeadViewPager extends React.Component {
render(){
let pic3 = {
uri: 'http://img0.ph.126.net/V946kkk3daLMuEuHNDPJAQ==/732679364477853939.png'
};
let pic4 = {
uri: 'http://i5.qhimg.com/t01d8897aa3b7010d89.jpg'
};
let pic5 = {
uri: 'http://www.qzhxw.com/d/file/p/0905/69ad0d2bb46f815a9550ad20c07494b4.jpg'
};
return(
<Swiper style={styles.wrapper} showsButtons={false} height={240} autoplay={true}>
<View>
<Image source={pic3} style={styles.pagerImageStyle}></Image>
</View>
<View>
<Image source={pic4} style={styles.pagerImageStyle}></Image>
</View>
<View>
<Image source={pic5} style={styles.pagerImageStyle}></Image>
</View>
</Swiper>
);
}
}
最后给上运行效果: