主要参考这位大侠的教程,跟着手写了一把:http://blog.csdn.net/yuanguozhengjust?viewmode=contents
(1)安装环境
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,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,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,TextInput,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',paddingTop: Platform.OS === 'ios' ? 20 : 0,// 处理iOS状态栏
- height: Platform.OS === 'ios' ? 68 : 48,// 处理iOS状态栏
- backgroundColor: '#d74047',logo: {
- height: 24,width: 64,resizeMode: 'stretch' // 设置拉伸模式
- },searchBox: {
- height: 30,flex: 1,// 类似于android中的layout_weight,设置为1即自动拉伸填充
- borderRadius: 5,// 设置圆角边
- backgroundColor: 'white',alignItems: 'center',marginLeft: 8,marginRight: 12
- },scanIcon: {
- height: 26.7,width: 26.7,searchIcon: {
- marginLeft: 6,marginRight: 6,width: 16.7,height: 16.7,voiceIcon: {
- marginLeft: 5,marginRight: 8,width: 15,height: 20,inputText: {
- flex: 1,backgroundColor: 'transparent',fontSize: 14
- }
- });
文件结构如下:
index.ios.js是程序入口,MainSceen.js定义首页视图,
Header.js定义头部,MenuButton.js定义首页按钮,Image文件夹用来存放图片。
最终实现效果如下:
详细请参考此博客:http://www.jb51.cc/article/p-amqrqgue-bgm.html
有问题欢迎交流。
案例下载地址:
http://download.csdn.net/detail/daleiwang/9434440
这里有位兄台总结了一些react native的学习资源比较全面:
http://blog.csdn.net/bondsui/article/details/49160649