主要参考这位大侠的教程,跟着手写了一把:http://blog.csdn.net/yuanguozhengjust?viewmode=contents
(1)安装环境
(2)命令行cd到项目文件夹下安装插件:
tabBar的插件:npm install i react-native-tab-navigator --save
轮转图片的插件:npm i -d react-native-viewpager --save
(3)开始编码:
index.ios.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';
import React, {
AppRegistry,
Component,
StyleSheet,
Text,
Image,
View
} from 'react-native';
import Header from './Header';
import MainScreen from './MainScreen';
import TabNavigator from 'react-native-tab-navigator';
const HOME = 'home';
const HOME_NORMAL = require('./images/tabs/home_normal.png');
const HOME_FOCUS = require('./images/tabs/home_focus.png');
const CATEGORY = 'category';
const CATEGORY_NORMAL = require('./images/tabs/category_normal.png');
const CATEGORY_FOCUS = require('./images/tabs/category_focus.png');
const FAXIAN = 'faxian';
const FAXIAN_NORMAL = require('./images/tabs/faxian_normal.png');
const FAXIAN_FOCUS = require('./images/tabs/faxian_focus.png');
const CART = 'cart';
const CART_NORMAL = require('./images/tabs/cart_normal.png');
const CART_FOCUS = require('./images/tabs/cart_focus.png');
const PERSONAL = 'personal';
const PERSONAL_NORMAL = require('./images/tabs/personal_normal.png');
const PERSONAL_FOCUS = require('./images/tabs/personal_focus.png');
class react_native_jd extends Component {
constructor(props) {
super(props);
this.state = {selectedTab: HOME}
}
_renderTabItem(img, selectedImg, tag, childView) {
return (
<TabNavigator.Item
selected={this.state.selectedTab === tag}
renderIcon={() => <Image style={styles.tabIcon} source={img}/>}
renderSelectedIcon={() => <Image style={styles.tabIcon} source={selectedImg}/>}
onPress={() => this.setState({ selectedTab: tag })}>
{childView}
</TabNavigator.Item>
);
}
static _createChildView(tag) {
return (
<View style={{flex:1,backgroundColor:'#00baff',alignItems:'center',justifyContent:'center'}}>
<Text style={{fontSize:22}}>{tag}</Text>
</View>
)
}
render() {
return (
<View style={{flex: 1}}>
<Header />
<TabNavigator hidesTabTouch={true} tabBarStyle={styles.tab}>
{this._renderTabItem(HOME_NORMAL, HOME_FOCUS, HOME, <MainScreen/>)}
{this._renderTabItem(CATEGORY_NORMAL, CATEGORY_FOCUS, CATEGORY, <MainScreen/>)}
{this._renderTabItem(FAXIAN_NORMAL, FAXIAN_FOCUS, FAXIAN, <MainScreen/>)}
{this._renderTabItem(CART_NORMAL, CART_FOCUS, CART, <MainScreen/>)}
{this._renderTabItem(PERSONAL_NORMAL, PERSONAL_FOCUS, PERSONAL, <MainScreen/>)}
</TabNavigator>
</View >
);
}
}
const styles = StyleSheet.create({
tab: {
height: 52,
backgroundColor: '#333333',
alignItems: 'center'
},
tabIcon: {
width: 30,
height: 35,
resizeMode: 'stretch',
marginTop: 12.5
},
});
AppRegistry.registerComponent('react_native_jd', () => react_native_jd);
MainScreen.js
'use strict';
import React, {
Component,
View,
Text,
Image,
StyleSheet,
ScrollView,
Alert,
RefreshControl
} from 'react-native';
import MenuButton from './MenuButton';
import ViewPager from 'react-native-viewpager';
const BANNER_IMGS = [
require('./images/banner/1.jpg'),
require('./images/banner/2.jpg'),
require('./images/banner/3.jpg'),
require('./images/banner/4.jpg')
];
export default class MainScreen extends Component {
constructor(props) {
super(props);
// 用于构建DataSource对象
var dataSource = new ViewPager.DataSource({
pageHasChanged: (p1, p2) => p1 !== p2,
});
// 实际的DataSources存放在state中
this.state = {
dataSource: dataSource.cloneWithPages(BANNER_IMGS)
}
}
_renderPage(data, pageID) {
return (
<Image source={data} style={styles.page}/>
);
}
_onMenuClick(title, tag) {
Alert.alert('提示', '你点击了:' + title + " Tag:" + tag);
}
render() {
return (
<View>
<ViewPager
style={{height:130}}
dataSource={this.state.dataSource}
renderPage={this._renderPage}
isLoop={true}
autoPlay={true}/>
<View style={styles.menuView}>
<MenuButton renderIcon={require('./images/home_icons/wdgz.png')}
showText={'我的关注'} tag={'wdgz'}
onClick={this._onMenuClick}/>
<MenuButton renderIcon={require('./images/home_icons/wlcx.png')}
showText={'物流查询'} tag={'wlcx'}
onClick={this._onMenuClick}/>
<MenuButton renderIcon={require('./images/home_icons/cz.png')}
showText={'充值'} tag={'cz'}
onClick={this._onMenuClick}/>
<MenuButton renderIcon={require('./images/home_icons/dyp.png')}
showText={'电影票'} tag={'dyp'}
onClick={this._onMenuClick}/>
</View>
<View style={styles.menuView}>
<MenuButton renderIcon={require('./images/home_icons/yxcz.png')}
showText={'游戏充值'} tag={'yxcz'}
onClick={this._onMenuClick}/>
<MenuButton renderIcon={require('./images/home_icons/xjk.png')}
showText={'小金库'} tag={'xjk'}
onClick={this._onMenuClick}/>
<MenuButton renderIcon={require('./images/home_icons/ljd.png')}
showText={'领京豆'} tag={'ljd'}
onClick={this._onMenuClick}/>
<MenuButton renderIcon={require('./images/home_icons/gd.png')}
showText={'更多'} tag={'gd'}
onClick={this._onMenuClick}/>
</View>
<View style={{marginTop:15,borderWidth:0.5,borderColor:'#ccc'}}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
height: 104,
flexDirection: 'row', // 水平排布
paddingLeft: 10,
paddingRight: 10,
backgroundColor: '#d74140',
alignItems: 'center' // 使元素垂直居中排布, 当flexDirection为column时, 为水平居中
},
page: {
flex: 1,
height: 130,
resizeMode: 'stretch'
},
menuView: {
flexDirection: 'row',
marginTop: 10
}
});
MenuButton.js
'use strict';
import React, {
Component,
View,
Text,
Image,
TouchableWithoutFeedback,
PropTypes,
StyleSheet
} from 'react-native';
export default class MenuButton extends Component {
static propTypes = {
renderIcon: PropTypes.number.isRequired, // 图片,加入.isRequired即为比填项
showText: PropTypes.string, // 显示标题\文字
tag: PropTypes.string, // Tag
onClick: PropTypes.func // 回调函数
};
constructor(props) {
super(props);
this._onClick = this._onClick.bind(this); // 需要在回调函数中使用this,必须使用bind(this)来绑定
}
_onClick() {
if (this.props.onClick) { // 在设置了回调函数的情况下
this.props.onClick(this.props.showText, this.props.tag); // 回调Title和Tag
}
}
render() {
return (
<TouchableWithoutFeedback onPress={this._onClick}>
<View style={{alignItems:'center',flex:1}}>
<Image style={styles.iconImg} source={this.props.renderIcon}/>
<Text style={styles.showText}>{this.props.showText}</Text>
</View>
</TouchableWithoutFeedback>
);
}
}
const styles = StyleSheet.create({
iconImg: {
width: 38,
height: 38,
marginBottom: 2
},
showText: {
fontSize: 12
}
});
Header.js
'use strict';
import React, {
Component,
Image,
TextInput,
View,
Platform,
StyleSheet
} from 'react-native';
export default class Header extends Component {
render() {
return (
<View style={styles.container}>
<Image source={require('./images/header/header_logo.png')} style={styles.logo}/>
<View style={styles.searchBox}>
<Image source={require('./images/header/icon_search.png')} style={styles.searchIcon}/>
<TextInput
keyboardType='web-search'
placeholder='搜索京东商品/店铺'
style={styles.inputText}/>
<Image source={require('./images/header/icon_voice.png')} style={styles.voiceIcon}/>
</View>
<Image source={require('./images/header/icon_qr.png')} style={styles.scanIcon}/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row', // 水平排布
paddingLeft: 10,
paddingRight: 10,
paddingTop: Platform.OS === 'ios' ? 20 : 0, // 处理iOS状态栏
height: Platform.OS === 'ios' ? 68 : 48, // 处理iOS状态栏
backgroundColor: '#d74047',
alignItems: 'center' // 使元素垂直居中排布, 当flexDirection为column时, 为水平居中
},
logo: {
height: 24,
width: 64,
resizeMode: 'stretch' // 设置拉伸模式
},
searchBox: {
height: 30,
flexDirection: 'row',
flex: 1, // 类似于android中的layout_weight,设置为1即自动拉伸填充
borderRadius: 5, // 设置圆角边
backgroundColor: 'white',
alignItems: 'center',
marginLeft: 8,
marginRight: 12
},
scanIcon: {
height: 26.7,
width: 26.7,
resizeMode: 'stretch'
},
searchIcon: {
marginLeft: 6,
marginRight: 6,
width: 16.7,
height: 16.7,
resizeMode: 'stretch'
},
voiceIcon: {
marginLeft: 5,
marginRight: 8,
width: 15,
height: 20,
resizeMode: 'stretch'
},
inputText: {
flex: 1,
backgroundColor: 'transparent',
fontSize: 14
}
});
文件结构如下:
index.ios.js是程序入口,MainSceen.js定义首页视图,
Header.js定义头部,MenuButton.js定义首页按钮,Image文件夹用来存放图片。
最终实现效果如下:
详细请参考此博客:http://blog.csdn.net/yuanguozhengjust/article/details/50556700
有问题欢迎交流。
案例下载地址:
http://download.csdn.net/detail/daleiwang/9434440
这里有位兄台总结了一些react native的学习资源比较全面:
http://blog.csdn.net/bondsui/article/details/49160649