react-native模仿京东首页

前端之家收集整理的这篇文章主要介绍了react-native模仿京东首页前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

主要参考这位大侠的教程,跟着手写了一把: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

  1. /**
  2. * Sample React Native App
  3. * https://github.com/facebook/react-native
  4. */
  5. 'use strict';
  6. import React,{
  7. AppRegistry,Component,StyleSheet,Text,Image,View
  8. } from 'react-native';
  9.  
  10. import Header from './Header';
  11. import MainScreen from './MainScreen';
  12. import TabNavigator from 'react-native-tab-navigator';
  13.  
  14. const HOME = 'home';
  15. const HOME_NORMAL = require('./images/tabs/home_normal.png');
  16. const HOME_FOCUS = require('./images/tabs/home_focus.png');
  17. const CATEGORY = 'category';
  18. const CATEGORY_NORMAL = require('./images/tabs/category_normal.png');
  19. const CATEGORY_FOCUS = require('./images/tabs/category_focus.png');
  20. const FAXIAN = 'faxian';
  21. const FAXIAN_NORMAL = require('./images/tabs/faxian_normal.png');
  22. const FAXIAN_FOCUS = require('./images/tabs/faxian_focus.png');
  23. const CART = 'cart';
  24. const CART_NORMAL = require('./images/tabs/cart_normal.png');
  25. const CART_FOCUS = require('./images/tabs/cart_focus.png');
  26. const PERSONAL = 'personal';
  27. const PERSONAL_NORMAL = require('./images/tabs/personal_normal.png');
  28. const PERSONAL_FOCUS = require('./images/tabs/personal_focus.png');
  29.  
  30. class react_native_jd extends Component {
  31.  
  32. constructor(props) {
  33. super(props);
  34. this.state = {selectedTab: HOME}
  35. }
  36.  
  37. _renderTabItem(img,selectedImg,tag,childView) {
  38. return (
  39. <TabNavigator.Item
  40. selected={this.state.selectedTab === tag}
  41. renderIcon={() => <Image style={styles.tabIcon} source={img}/>}
  42. renderSelectedIcon={() => <Image style={styles.tabIcon} source={selectedImg}/>}
  43. onPress={() => this.setState({ selectedTab: tag })}>
  44. {childView}
  45. </TabNavigator.Item>
  46. );
  47. }
  48.  
  49. static _createChildView(tag) {
  50. return (
  51. <View style={{flex:1,backgroundColor:'#00baff',alignItems:'center',justifyContent:'center'}}>
  52. <Text style={{fontSize:22}}>{tag}</Text>
  53. </View>
  54. )
  55. }
  56.  
  57. render() {
  58. return (
  59. <View style={{flex: 1}}>
  60. <Header />
  61. <TabNavigator hidesTabTouch={true} tabBarStyle={styles.tab}>
  62. {this._renderTabItem(HOME_NORMAL,HOME_FOCUS,HOME,<MainScreen/>)}
  63. {this._renderTabItem(CATEGORY_NORMAL,CATEGORY_FOCUS,CATEGORY,<MainScreen/>)}
  64. {this._renderTabItem(FAXIAN_NORMAL,FAXIAN_FOCUS,FAXIAN,<MainScreen/>)}
  65. {this._renderTabItem(CART_NORMAL,CART_FOCUS,CART,<MainScreen/>)}
  66. {this._renderTabItem(PERSONAL_NORMAL,PERSONAL_FOCUS,PERSONAL,<MainScreen/>)}
  67. </TabNavigator>
  68. </View >
  69. );
  70. }
  71. }
  72.  
  73. const styles = StyleSheet.create({
  74. tab: {
  75. height: 52,backgroundColor: '#333333',alignItems: 'center'
  76. },tabIcon: {
  77. width: 30,height: 35,resizeMode: 'stretch',marginTop: 12.5
  78. },});
  79.  
  80. AppRegistry.registerComponent('react_native_jd',() => react_native_jd);

MainScreen.js
  1. 'use strict';
  2.  
  3. import React,{
  4. Component,View,ScrollView,Alert,RefreshControl
  5. } from 'react-native';
  6.  
  7. import MenuButton from './MenuButton';
  8. import ViewPager from 'react-native-viewpager';
  9.  
  10. const BANNER_IMGS = [
  11. require('./images/banner/1.jpg'),require('./images/banner/2.jpg'),require('./images/banner/3.jpg'),require('./images/banner/4.jpg')
  12. ];
  13.  
  14. export default class MainScreen extends Component {
  15.  
  16. constructor(props) {
  17. super(props);
  18. // 用于构建DataSource对象
  19. var dataSource = new ViewPager.DataSource({
  20. pageHasChanged: (p1,p2) => p1 !== p2,});
  21. // 实际的DataSources存放在state中
  22. this.state = {
  23. dataSource: dataSource.cloneWithPages(BANNER_IMGS)
  24. }
  25. }
  26.  
  27. _renderPage(data,pageID) {
  28. return (
  29. <Image source={data} style={styles.page}/>
  30. );
  31. }
  32. _onMenuClick(title,tag) {
  33. Alert.alert('提示','你点击了:' + title + " Tag:" + tag);
  34. }
  35.  
  36. render() {
  37. return (
  38. <View>
  39. <ViewPager
  40. style={{height:130}}
  41. dataSource={this.state.dataSource}
  42. renderPage={this._renderPage}
  43. isLoop={true}
  44. autoPlay={true}/>
  45. <View style={styles.menuView}>
  46. <MenuButton renderIcon={require('./images/home_icons/wdgz.png')}
  47. showText={'我的关注'} tag={'wdgz'}
  48. onClick={this._onMenuClick}/>
  49. <MenuButton renderIcon={require('./images/home_icons/wlcx.png')}
  50. showText={'物流查询'} tag={'wlcx'}
  51. onClick={this._onMenuClick}/>
  52. <MenuButton renderIcon={require('./images/home_icons/cz.png')}
  53. showText={'充值'} tag={'cz'}
  54. onClick={this._onMenuClick}/>
  55. <MenuButton renderIcon={require('./images/home_icons/dyp.png')}
  56. showText={'电影票'} tag={'dyp'}
  57. onClick={this._onMenuClick}/>
  58. </View>
  59. <View style={styles.menuView}>
  60. <MenuButton renderIcon={require('./images/home_icons/yxcz.png')}
  61. showText={'游戏充值'} tag={'yxcz'}
  62. onClick={this._onMenuClick}/>
  63. <MenuButton renderIcon={require('./images/home_icons/xjk.png')}
  64. showText={'小金库'} tag={'xjk'}
  65. onClick={this._onMenuClick}/>
  66. <MenuButton renderIcon={require('./images/home_icons/ljd.png')}
  67. showText={'领京豆'} tag={'ljd'}
  68. onClick={this._onMenuClick}/>
  69. <MenuButton renderIcon={require('./images/home_icons/gd.png')}
  70. showText={'更多'} tag={'gd'}
  71. onClick={this._onMenuClick}/>
  72. </View>
  73. <View style={{marginTop:15,borderWidth:0.5,borderColor:'#ccc'}}/>
  74. </View>
  75. );
  76. }
  77. }
  78.  
  79. const styles = StyleSheet.create({
  80. container: {
  81. height: 104,flexDirection: 'row',// 水平排布
  82. paddingLeft: 10,paddingRight: 10,backgroundColor: '#d74140',alignItems: 'center' // 使元素垂直居中排布,当flexDirection为column时,为水平居中
  83. },page: {
  84. flex: 1,height: 130,resizeMode: 'stretch'
  85. },menuView: {
  86. flexDirection: 'row',marginTop: 10
  87. }
  88. });

MenuButton.js
  1. 'use strict';
  2.  
  3. import React,TouchableWithoutFeedback,PropTypes,StyleSheet
  4. } from 'react-native';
  5.  
  6. export default class MenuButton extends Component {
  7.  
  8. static propTypes = {
  9. renderIcon: PropTypes.number.isrequired,// 图片,加入.isrequired即为比填项
  10. showText: PropTypes.string,// 显示标题\文字
  11. tag: PropTypes.string,// Tag
  12. onClick: PropTypes.func // 回调函数
  13. };
  14.  
  15. constructor(props) {
  16. super(props);
  17. this._onClick = this._onClick.bind(this); // 需要在回调函数中使用this,必须使用bind(this)来绑定
  18. }
  19.  
  20. _onClick() {
  21. if (this.props.onClick) { // 在设置了回调函数的情况下
  22. this.props.onClick(this.props.showText,this.props.tag); // 回调Title和Tag
  23. }
  24. }
  25.  
  26. render() {
  27. return (
  28. <TouchableWithoutFeedback onPress={this._onClick}>
  29. <View style={{alignItems:'center',flex:1}}>
  30. <Image style={styles.iconImg} source={this.props.renderIcon}/>
  31. <Text style={styles.showText}>{this.props.showText}</Text>
  32. </View>
  33. </TouchableWithoutFeedback>
  34. );
  35. }
  36. }
  37.  
  38. const styles = StyleSheet.create({
  39. iconImg: {
  40. width: 38,height: 38,marginBottom: 2
  41. },showText: {
  42. fontSize: 12
  43. }
  44. });

Header.js
  1. 'use strict';
  2.  
  3. import React,TextInput,Platform,StyleSheet
  4. } from 'react-native';
  5.  
  6. export default class Header extends Component {
  7. render() {
  8. return (
  9. <View style={styles.container}>
  10. <Image source={require('./images/header/header_logo.png')} style={styles.logo}/>
  11. <View style={styles.searchBox}>
  12. <Image source={require('./images/header/icon_search.png')} style={styles.searchIcon}/>
  13. <TextInput
  14. keyboardType='web-search'
  15. placeholder='搜索京东商品/店铺'
  16. style={styles.inputText}/>
  17. <Image source={require('./images/header/icon_voice.png')} style={styles.voiceIcon}/>
  18. </View>
  19. <Image source={require('./images/header/icon_qr.png')} style={styles.scanIcon}/>
  20. </View>
  21. )
  22. }
  23. }
  24.  
  25. const styles = StyleSheet.create({
  26. container: {
  27. flexDirection: 'row',paddingTop: Platform.OS === 'ios' ? 20 : 0,// 处理iOS状态栏
  28. height: Platform.OS === 'ios' ? 68 : 48,// 处理iOS状态栏
  29. backgroundColor: '#d74047',logo: {
  30. height: 24,width: 64,resizeMode: 'stretch' // 设置拉伸模式
  31. },searchBox: {
  32. height: 30,flex: 1,// 类似于android中的layout_weight,设置为1即自动拉伸填充
  33. borderRadius: 5,// 设置圆角边
  34. backgroundColor: 'white',alignItems: 'center',marginLeft: 8,marginRight: 12
  35. },scanIcon: {
  36. height: 26.7,width: 26.7,searchIcon: {
  37. marginLeft: 6,marginRight: 6,width: 16.7,height: 16.7,voiceIcon: {
  38. marginLeft: 5,marginRight: 8,width: 15,height: 20,inputText: {
  39. flex: 1,backgroundColor: 'transparent',fontSize: 14
  40. }
  41. });

文件结构如下:


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

猜你在找的React相关文章