React Native商城项目实战12 - 首页头部内容

1.HomeTopView为首页头部内容,HomeTopListView为HomeTopView子视图。

 

2.HomeTopView.js

/**
 * 首页头部内容
 */
import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    ScrollView,
    Image,
    ListView
} from 'react-native';

var Dimensions = require('Dimensions');
var screenW = Dimensions.get('window').width;

/*======导入外部组件类======*/
var TopListView = require('./HomeTopListView');

// 导入外部json数据
var TopMenuJSON = require('../../LocalData/TopMenu.json');

// ES5
var TopView = React.createClass({
    getInitialState(){
        return{
            activePage:0,
        }
    },

    render() {
        return (
            <View style={styles.container}>
                {/*内容部分*/}
                <ScrollView
                    horizontal={true}
                    pagingEnabled={true}
                    showsHorizontalScrollIndicator={false}
                    onMomentumScrollEnd={this.onScrollAnimationEnd}
                >
                    {this.renderScrollItem()}
                </ScrollView>
                {/*页码*/}
                <View style={styles.indicatorViewStyle}>
                    {this.renderIndicator()}
                </View>
            </View>
        );
    },

    // 当一帧滚动结束的时候调用
    onScrollAnimationEnd(e){
        // 计算当前页码
        var currentPage = Math.floor(e.nativeEvent.contentOffset.x / screenW);
        // 更新状态机
        this.setState({
            activePage:currentPage,
        });
    },

    // 返回子视图
    renderScrollItem(){
        var itemArr = [];
        var dataArr = TopMenuJSON.data;
        for (var i=0;i<dataArr.length;i++){
            itemArr.push(
                <TopListView
                    key={i}
                    dataArr={dataArr[i]}
                />
            );
        }
        return itemArr;
    },

    // 返回页码视图
    renderIndicator(){
        var indicatorArr = [],style;

        for (var i=0;i<2;i++){
            // 设置圆点的样式
            style = (i == this.state.activePage) ? {color:'orange'} : {color:'gray'};
            indicatorArr.push(
                <Text key={i} style={[{fontSize:25},style]}>•</Text>
            );
        }
        return indicatorArr;
    }
});

const styles = StyleSheet.create({
    container: {
        backgroundColor: 'white',
    },
    indicatorViewStyle:{
        flexDirection:'row',
        justifyContent:'center',
    },
});

// 输出
module.exports = TopView;

 

3.HomeTopListView.js

/**
 * HomeTopView子视图
 */
import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    Image,
    ListView,
    TouchableOpacity,
    Platform
} from 'react-native';

var Dimensions = require('Dimensions');
var screenW = Dimensions.get('window').width;

// 全局常量
const cols = 5
const cellW = Platform.OS == 'ios' ? 70 : 60;
const cellH = 70;
const vMargin = (screenW - cellW * cols) / (cols + 1);


// ES5
var TopListView = React.createClass({
    getDefaultProps(){
        return{
            dataArr:[],
        }
    },
    getInitialState(){
        // 创建数据源
        var ds = new ListView.DataSource({rowHasChanged:(row1,row2)=>row1 !== row2});
        return{
            dataSource:ds.cloneWithRows(this.props.dataArr)
        }
    },

    render() {
        return (
            <ListView
                dataSource={this.state.dataSource}
                renderRow={this.renderRow}
                contentContainerStyle={styles.contentViewStyle}
                scrollEnabled={false}
            />
        );
    },

    // 返回具体的一行
    renderRow(rowData){
        return(
            <TouchableOpacity activeOpacity={0.8}>
                <View style={styles.cellStyle}>
                    <Image source={{uri:rowData.image}} style={{width:52,height:52}} />
                    <Text style={styles.titleStyle}>{rowData.title}</Text>
                </View>
            </TouchableOpacity>
        )
    }
});

const styles = StyleSheet.create({
    contentViewStyle:{
        flexDirection:'row',
        flexWrap:'wrap',
        width:screenW,
        alignItems:'center',
        justifyContent:'center',
    },
    cellStyle:{
        alignItems:'center',
        justifyContent:'center',
        marginTop:10,
        width:cellW,
        height:cellH,
        marginLeft:vMargin,
    },
    titleStyle:{
        fontSize:Platform.OS == 'ios' ? 14 : 12,
        color:'gray'
    },
});

// 输出
module.exports = TopListView;

 

4.Home.js 引入 HomeTopView 组件

/**
 * 首页
 */
import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    TouchableOpacity,
    TextInput,
    Image,
    Platform,
    ScrollView
} from 'react-native';

var Dimensions = require('Dimensions');
var screenW = Dimensions.get('window').width;
var screenH = Dimensions.get('window').height;

/*======导入外部组件类======*/
var HomeDetail = require('./HomeDetail');
var TopView = require('./HomeTopView');

// ES5
var Home = React.createClass({
    render() {
        return (
            <View style={styles.container}>
                {/*首页的导航条*/}
                {this.renderNavBar()}
                {/*首页主要内容*/}
                <ScrollView>
                    {/*头部的View*/}
                   <TopView />
                </ScrollView>
            </View>
        );
    },

    // 首页的导航条
    renderNavBar(){
        return(
            <View style={styles.navBarStyle}>
                <TouchableOpacity onPress={()=>{this.pushToDetail()}} >
                    <Text style={styles.leftTitleStyle}>宁波</Text>
                </TouchableOpacity>
                <TextInput placeholder="输入商家,品类,商圈" style={styles.topInputStyle} />
                <View style={styles.rightNavViewStyle}>
                    <TouchableOpacity onPress={()=>{alert('点击了')}} >
                        <Image source={{uri:'icon_homepage_message'}} style={styles.navRightImgStyle} />
                    </TouchableOpacity>
                    <TouchableOpacity onPress={()=>{alert('点击了')}} >
                        <Image source={{uri:'icon_homepage_scan'}} style={styles.navRightImgStyle} />
                    </TouchableOpacity>
                </View>
            </View>
        )
    },

    // 跳转到首页详细页
    pushToDetail(data){
        this.props.navigator.push({
            component:HomeDetail,   // 要跳转过去的组件
            title:'首页详细页'
        });
    },
});

const styles = StyleSheet.create({
    // 导航栏
    navBarStyle:{
        height:Platform.OS === 'ios' ? 64 : 44,
        backgroundColor:'rgba(255,96,0,1)',
        // 主轴方向
        flexDirection:'row',
        // 侧轴对齐方式 垂直居中
        alignItems:'center',
        // 主轴对齐方式
        justifyContent:'space-around', // 平均分布
    },
    // 导航条左侧文字
    leftTitleStyle:{
        color:'white',
        fontSize:16,
    },
    // 导航栏输入框
    topInputStyle:{
        width:screenW * 0.71,
        height:Platform.OS === 'ios' ? 35 : 30,
        backgroundColor:'white',
        marginTop:Platform.OS === 'ios' ? 18 : 0,
        // 圆角
        borderRadius:18,
        paddingLeft:10,
    },
    // 导航条右侧视图
    rightNavViewStyle:{
        flexDirection:'row',
        height:64,
        // 侧轴对齐方式
        alignItems:'center',
        // backgroundColor:'blue',
    },
    // 导航栏右侧图片
    navRightImgStyle:{
        width:Platform.OS === 'ios' ? 28 : 24,
        height:Platform.OS === 'ios' ? 28 : 24,
    },
    container: {
        flex: 1,
        backgroundColor: '#e8e8e8',
    },
    welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    },

});

// 输出
module.exports = Home;

 

5.json数据 

{
  "data": [
    [{
      "title" : "美食",
      "image" : "ms"
    },
    {
      "title" : "电影",
      "image" : "dy"
    },
    {
      "title" : "酒店",
      "image" : "jd"
    },
    {
      "title" : "休闲娱乐",
      "image" : "xxyl"
    },
    {
      "title" : "外卖",
      "image" : "wm"
    },
    {
      "title" : "自助餐",
      "image" : "zzc"
    },
    {
      "title" : "KTV",
      "image" : "ktv"
    },
    {
      "title" : "火车票机票",
      "image" : "hcpjp"
    },
    {
      "title" : "丽人",
      "image" : "lr"
    },
    {
        "title" : "周边游",
        "image" : "zby"
    }
    ],
    [
    {
      "title" : "足疗按摩",
      "image" : "zlam"
    },
    {
      "title" : "购物",
      "image" : "gw"
    },
    {
      "title" : "今日新单",
      "image" : "jrxd"
    },
    {
      "title" : "小吃快餐",
      "image" : "xckc"
    },
    {
      "title" : "生活服务",
      "image" : "shfw"
    },
      {
        "title" : "甜点饮品",
        "image" : "tdyp"
      },
    {
      "title" : "美甲",
      "image" : "mj"
    },
    {
      "title" : "景点门票",
      "image" : "jdmp"
    },
    {
      "title" : "旅游",
      "image" : "ly"
    },
    {
      "title" : "全部分类",
      "image" : "qbfl"
    }]
  ]
}

  

6.效果图

posted @ 2017-08-18 18:59  每天都要进步一点点  阅读(498)  评论(0编辑  收藏  举报