React-NativeReact Native

React-Native 之 项目实战(二)

2017-03-22  本文已影响710人  珍此良辰

前言


属性声明和属性确定


    static propTypes = {
        name:PropTypes.string,
        ID:PropTypes.number.isRequired,
    }

占位图


     {/* 左边图片 */}
     <Image source={{uri:this.props.image === '' ? 'defaullt_thumb_83x83' : this.props.image}} style={styles.imageStyle} />

占位图.png

无数据情况处理


    import React, { Component } from 'react';
    import {
        StyleSheet,
        View,
        Text,
    } from 'react-native';

    export default class GDNoDataView extends Component {

        render() {
            return(
                <View style={styles.container}>
                    <Text style={styles.textStyle}>无数据  </Text>
                </View>
            );

        }
    }

    const styles = StyleSheet.create({
        container: {
            flex:1,
            justifyContent:'center',
            alignItems:'center',
        },

        textStyle: {
            fontSize:21,
            color:'gray'
        }
    });
    
    // 根据网络状态决定是否渲染 listview
    renderListView() {
        if (this.state.loaded === false) {
            return(
                <NoDataView />
            );
        }else {
            return(
                <PullList
                    onPullRelease={(resolve) => this.fetchData(resolve)}
                    dataSource={this.state.dataSource}
                    renderRow={this.renderRow}
                    showsHorizontalScrollIndicator={false}
                    style={styles.listViewStyle}
                    initialListSize={5}
                />
            );
        }
    }

无数据界面.png

listView 头部设置


    <ListView
             dataSource={this.state.dataSource}
             renderRow={this.renderRow}
             showsHorizontalScrollIndicator={false}
             style={styles.listViewStyle}
             initialListSize={5}
             renderHeader={this.renderHeader}
   />

    // 返回 listview 头部
    renderHeader() {
        return (
            <View style={styles.headerPromptStyle}>
                <Text>根据每条折扣的点击进行统计,每5分钟更新一次</Text>
            </View>
        );
    }
    
ListView头部.gif

下拉刷新


    <PullList
            onPullRelease={(resolve) => this.fetchData(resolve)}
            dataSource={this.state.dataSource}
            renderRow={this.renderRow}
            showsHorizontalScrollIndicator={false}
            style={styles.listViewStyle}
            initialListSize={5}
            renderHeader={this.renderHeader}
   />
                
    // 网络请求
    fetchData(resolve) {
        setTimeout(() => {
            fetch('http://guangdiu.com/api/gethots.php')
                .then((response) => response.json())
                .then((responseData) => {
                    this.setState({
                        dataSource: this.state.dataSource.cloneWithRows(responseData.data),
                        loaded:true,
                    });
                    if (resolve !== undefined){
                        setTimeout(() => {
                            resolve();  // 关闭动画
                        }, 1000);
                    }
                })
                .done();
        });
    }

下拉刷新.gif

网络请求之POST(重要)


    let formData = new FormData();
    formData.append("参数", "值");
    formData.append("参数", "值");
    
    fetch(url, {
        method:'POST,
        headers:{},
        body:formData,
        }).then((response)=>{
            if (response.ok) {
                return response.json();
            }
        }).then((json)=>{
            alert(JSON.stringify(json));
        }).catch.((error)=>{
            console.error(error);
        })

首页模块


    import React, { Component } from 'react';
    import {
        StyleSheet,
        Text,
        View,
        TouchableOpacity,
        Image,
        ListView,
        Dimensions
    } from 'react-native';
    
    // 第三方
    import {PullList} from 'react-native-pull';
    
    const {width, height} = Dimensions.get('window');
    
    // 引用外部文件
    import CommunalNavBar from '../main/GDCommunalNavBar';
    import CommunalHotCell from '../main/GDCommunalHotCell';
    import HalfHourHot from './GDHalfHourHot';
    import Search from './GDSearch';
    
    export default class GDHome extends Component {
    
        // 构造
        constructor(props) {
            super(props);
            // 初始状态
            this.state = {
                dataSource: new ListView.DataSource({rowHasChanged:(r1, r2) => r1 !== r2}),
                loaded:true,
            };
            this.fetchData = this.fetchData.bind(this);
        }
    
        // 网络请求
        fetchData(resolve) {
            let formData = new FormData();
            formData.append("count", "30");
    
            setTimeout(() => {
                fetch('http://guangdiu.com/api/getlist.php', {
                    method:'POST',
                    headers:{},
                    body:formData,
                })
                .then((response) => response.json())
                .then((responseData) => {
                    this.setState({
                        dataSource: this.state.dataSource.cloneWithRows(responseData.data),
                        loaded:true,
                    });
                    if (resolve !== undefined){
                        setTimeout(() => {
                            resolve();
                        }, 1000);
                    }
                })
                .done();
            });
        }
    
        // 跳转到近半小时热门
        pushToHalfHourHot() {
            this.props.navigator.push({
                component: HalfHourHot,
            })
        }
    
        // 跳转到搜索
        pushToSearch() {
            this.props.navigator.push({
                component:Search,
            })
        }
    
        // 返回左边按钮
        renderLeftItem() {
            return(
                <TouchableOpacity
                    onPress={() => {this.pushToHalfHourHot()}}
                >
                    <Image source={{uri:'hot_icon_20x20'}} style={styles.navbarLeftItemStyle} />
                </TouchableOpacity>
            );
        }
    
        // 返回中间按钮
        renderTitleItem() {
            return(
                <TouchableOpacity>
                    <Image source={{uri:'navtitle_home_down_66x20'}} style={styles.navbarTitleItemStyle} />
                </TouchableOpacity>
            );
        }
    
        // 返回右边按钮
        renderRightItem() {
            return(
                <TouchableOpacity
                    onPress={()=>{this.pushToSearch()}}
                >
                    <Image source={{uri:'search_icon_20x20'}} style={styles.navbarRightItemStyle} />
                </TouchableOpacity>
            );
        }
    
        // 根据网络状态决定是否渲染 listview
        renderListView() {
            if (this.state.loaded === false) {
                return(
                    <NoDataView />
                );
            }else {
                return(
                    <PullList
                        onPullRelease={(resolve) => this.fetchData(resolve)}
                        dataSource={this.state.dataSource}
                        renderRow={this.renderRow}
                        showsHorizontalScrollIndicator={false}
                        style={styles.listViewStyle}
                        initialListSize={5}
                        renderHeader={this.renderHeader}
                    />
                );
            }
        }
    
        // 返回每一行cell的样式
        renderRow(rowData) {
            return(
                <CommunalHotCell
                    image={rowData.image}
                    title={rowData.title}
                />
            );
        }
    
        componentDidMount() {
            this.fetchData();
        }
    
    
        render() {
            return (
                <View style={styles.container}>
                    {/* 导航栏样式 */}
                    <CommunalNavBar
                        leftItem = {() => this.renderLeftItem()}
                        titleItem = {() => this.renderTitleItem()}
                        rightItem = {() => this.renderRightItem()}
                    />
    
                    {/* 根据网络状态决定是否渲染 listview */}
                    {this.renderListView()}
                </View>
            );
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            alignItems: 'center',
            backgroundColor: 'white',
        },
    
        navbarLeftItemStyle: {
            width:20,
            height:20,
            marginLeft:15,
        },
        navbarTitleItemStyle: {
            width:66,
            height:20,
        },
        navbarRightItemStyle: {
            width:20,
            height:20,
            marginRight:15,
        },
    
        listViewStyle: {
            width:width,
        },
    });

首页数据效果.gif

效果:

navigator 跳转动画



// 设置跳转动画
configureScene={(route) => this.setNavAnimationType(route)}

// 设置Navigator跳转动画
    setNavAnimationType(route) {
        if (route.animationType) {  // 有值
            return route.animationType;
        }else {
            return Navigator.SceneConfigs.PushFromRight;
        }
    }


    // 跳转到近半小时热门
        pushToHalfHourHot() {
            this.props.navigator.push({
                component: HalfHourHot,
                animationType:Navigator.SceneConfigs.FloatFromBottom
            })
        }

navigator跳转动画.gif

关闭 Navigator 返回手势


    // 设置Navigator跳转动画
    setNavAnimationType(route) {
        if (route.animationType) {  // 有值
            let conf = route.animationType;
            conf.gestures = null;   // 关闭返回手势
            return conf;
        }else {
            return Navigator.SceneConfigs.PushFromRight;
        }
    }

navigator返回手势关闭.gif

上拉加载更多


    loadMore() {
        // 数据加载操作
    }

    renderFooter() {
        return (
            <View style={{height: 100}}>
                <ActivityIndicator />
            </View>
        );
    }

    // 根据网络状态决定是否渲染 listview
    renderListView() {
        if (this.state.loaded === false) {
            return(
                <NoDataView />
            );
        }else {
            return(
                <PullList
                    onPullRelease={(resolve) => this.fetchData(resolve)}
                    dataSource={this.state.dataSource}
                    renderRow={this.renderRow}
                    showsHorizontalScrollIndicator={false}
                    style={styles.listViewStyle}
                    initialListSize={5}
                    renderHeader={this.renderHeader}
                    onEndReached={this.loadMore}
                    onEndReachedThreshold={60}
                    renderFooter={this.renderFooter}
                />
            );
        }
    }
    
上拉加载更多.gif

网络请求基础封装


    var HTTPBase = {};

    /**
     *
     * GET请求
     *
     * @param url
     * @param params {}包装
     * @param headers
     *
     * @return {Promise}
     *
     * */
    HTTPBase.get = function (url, params, headers) {
        if (params) {
    
            let paramsArray = [];
    
            // 获取 params 内所有的 key
            let paramsKeyArray = Object.keys(params);
            // 通过 forEach 方法拿到数组中每个元素,将元素与参数的值进行拼接处理,并且放入 paramsArray 中
            paramsKeyArray.forEach(key => paramsArray.push(key + '=' + params[key]));
    
            // 网址拼接
            if (url.search(/\?/) === -1) {
                url += '?' + paramsArray.join('&');
            }else {
                url += paramsArray.join('&');
            }
        }
    
        return new Promise(function (resolve, reject) {
            fetch(url, {
                method:'GET',
                headers:headers
            })
                .then((response) => response.json())
                .then((response) => {
                    resolve(response);
                })
                .catch((error) => {
                    reject({status:-1})
                })
                .done();
        })
    }

    fetchData(resolve) {
        HTTPBase.get('http://guangdiu.com/api/gethots.php')
            .then((responseData) => {
                this.setState({
                    dataSource: this.state.dataSource.cloneWithRows(responseData.data),
                    loaded:true,
                });
                if (resolve !== undefined){
                    setTimeout(() => {
                        resolve();  // 关闭动画
                    }, 1000);
                }
            })
            .catch((error) => {

            })
    }
    
    export default HTTPBase;

    /**
     *
     * POST请求
     *
     * @param url
     * @param params {}包装
     * @param headers
     *
     * @return {Promise}
     *
     * */
    HTTPBase.post = function (url, params, headers) {
        if (params) {
            // 初始化FormData
            var formData = new FormData();
    
            // 获取 params 内所有的 key
            let paramsKeyArray = Object.keys(params);
            // 通过 forEach 方法拿到数组中每个元素,将元素与参数的值进行拼接处理,并且放入 paramsArray 中
            paramsKeyArray.forEach(key => formData.append(key, params[key]));
        }
    
        return new Promise(function (resolve, reject) {
            fetch(url, {
                method:'POST',
                headers:headers,
                body:formData,
            })
                .then((response) => response.json())
                .then((response) => {
                    resolve(response);
                })
                .catch((error) => {
                    reject({status:-1})
                })
                .done();
        })
    }
    
    export default HTTPBase;

    // 网络请求
    fetchData(resolve) {

        let params = {"count" : 5 };

        HTTPBase.post('http://guangdiu.com/api/getlist.php', params)
            .then((responseData) => {
                this.setState({
                    dataSource: this.state.dataSource.cloneWithRows(responseData.data),
                    loaded:true,
                });
                if (resolve !== undefined){
                    setTimeout(() => {
                        resolve();
                    }, 1000);
                }
            })
            .catch((error) => {

            })
    }

上一篇 下一篇

猜你喜欢

热点阅读