zoukankan      html  css  js  c++  java
  • React-Native 之 GD (十三)数据持久化(realm) 及 公共Cell

    1.数据持久化

    数据持久化是移动端的一个重要部分,刚发现 Realm 原来已经支持 React-Native 了

    步骤一: 引入 realm

    $ npm install realm --save
    

    步骤二: 添加 Realm 与 工程的链接

    react-native >= 0.31.0

    react-native link realm

    react-native  <  0.31.0

    rnpm link realm
    

     首先,在为了方便使用,也为了减少第三方框架对工程的 “污染”,我们需要对框架进行一次 基础 的封装。

    realmStorage.js

    /**
     * 数据持久化
     * 本地数据存储
     */
    // 提供变量,便于外部调用
    var RealmBase = {};
    
    import Realm from 'realm';
    
    // 创建数据表(首页)
    const HomeSchame = {
        name:'HomeData',
        properties:{
            id:'int',
            title:'string',
            image:'string',
            mall:'string', // 商城平台
            pubtime:'string',
            fromsite:'string',
        }
    };
    
    // 创建数据表(海淘)
    const HTSchame = {
        name:'HTData',
        properties:{
            id:'int',
            title:'string',
            image:'string',
            mall:'string',
            pubtime:'string',
            fromsite:'string',
        }
    };
    
    // 初始化realm
    let realm = new Realm({schema:[HomeSchame, HTSchame]});
    
    // 增加
    RealmBase.create = function (schame, data) {
        realm.write(() => {
            for (let i = 0; i<data.length; i++) {
                let temp = data[i];
                realm.create(schame, {id:temp.id, title:temp.title, image:temp.image, mall:temp.mall, pubtime:temp.pubtime, fromsite:temp.fromsite});
            }
        })
    }
    
    // 查询全部数据
    RealmBase.loadAll = function (schame) {
        return realm.objects(schame);
    }
    
    // 条件查询
    RealmBase.filtered = function (schame, filtered) {
        // 获取对象
        let objects = realm.objects(schame);
        // 筛选
        let object = objects.filtered(filtered);
    
        if (object) {   // 有对象
            return object;
        }else {
            return '未找到数据';
        }
    }
    
    // 删除所有数据
    RealmBase.removeAllData = function (schame) {
        realm.write(() => {
            // 获取对象
            let objects = realm.objects(schame);
            // 删除表
            realm.delete(objects);
        })
    }
    
    global.RealmBase = RealmBase;
    

    GDMain.js 调用

    // 引入 HTTP封装组件
    import HTTP from '../http/HTTPBase';
    
    // 引入 本地数据存储封装组件 (数据持久化)
    import RealmStorage from '../storage/realmStorage';

    GDHome.js

    /**
     * 首页
     */
    import React, { Component } from 'react';
    import {
        StyleSheet,
        Text,
        View,
        TouchableOpacity,
        Image,
        ListView,
        Dimensions,
        ActivityIndicator,
        Modal, // 模态
        AsyncStorage, // 缓存数据库(数据持久化)
    } from 'react-native';
    
    // 引入 下拉刷新组件
    import {PullList} from 'react-native-pull';
    // 导航器
    import CustomerComponents, {
        Navigator
    } from 'react-native-deprecated-custom-components';
    
    // 获取屏幕宽高
    const {width, height} = Dimensions.get('window');
    
    // 引入自定义导航栏组件
    import CommunalNavBar from '../main/GDCommunalNavBar';
    // 引入 近半小时热门组件
    import HalfHourHot from './GDHalfHourHot';
    // 引入 搜索页面组件
    import Search from '../main/GDSearch';
    // 引入 cell
    import CommunalHotCell from '../main/GDCommunalHotCell';
    // 引入 详情页 组件
    import CommunalDetail from '../main/GDCommunalDetail';
    // 引入 空白页组件
    import NoDataView from '../main/GDNoDataView';
    
    export default class GDHome extends Component {
    
        // 构造
        constructor(props) {
            super(props);
            // 初始状态
            this.state = {
                dataSource: new ListView.DataSource({rowHasChanged:(r1, r2) => r1 !== r2}), // 数据源 优化
                loaded: false, // 用于判断是否显示空白页
                isModal: false, // 用于判断模态的可见性
            };
            // 全局定义一个空数组用于存储列表数据
            this.data = [];
            // 绑定
            this.loadData = this.loadData.bind(this);
            this.loadMore = this.loadMore.bind(this);
        }
    
        // 加载最新数据网络请求
        loadData(resolve) {
    
            let params = {"count" : 10 };
    
            HTTPBase.get('https://guangdiu.com/api/getlist.php', params)
                .then((responseData) => {
    
                    // 情况数组(刷新时)
                    this.data = [];
    
                    // 拼接数据
                    this.data = this.data.concat(responseData.data);
    
                    // 重新渲染
                    this.setState({
                        dataSource: this.state.dataSource.cloneWithRows(this.data),
                        loaded:true,
                    });
    
                    // 关闭刷新动画
                    if (resolve !== undefined){
                        setTimeout(() => {
                            resolve();
                        }, 1000);
                    }
    
                    // 存储数组中最后一个元素的id
                    let cnlastID = responseData.data[responseData.data.length - 1].id;
                    AsyncStorage.setItem('cnlastID', cnlastID.toString());  // 只能存储字符或字符串
    
                    // 首页存储数组中第一个元素的id
                    let cnfirstID = responseData.data[0].id;
                    AsyncStorage.setItem('cnfirstID', cnfirstID.toString());
    
                     // 清除本地存储的数据
                    RealmBase.removeAllData('HomeData');
    
                    // 存储数据到本地
                    RealmBase.create('HomeData', responseData.data); // 向数据表存储数据
                })
                .catch((error) => {
                    // 数据加载失败,拿到本地存储的数据,展示出来,如果没有存储,那就显示无数据页面
                    this.data = RealmBase.loadAll('HomeData'); // 从数据表提取数据
    
                    // 重新渲染
                    this.setState({
                        dataSource: this.state.dataSource.cloneWithRows(this.data),
                        loaded:true,
                    });
                })
        }
    
        // 加载更多数据的网络请求
        loadMoreData(value) {
    
            let params = {
                "count" : 10,
                "sinceid" : value 
            };
    
            HTTPBase.get('https://guangdiu.com/api/getlist.php', params)
                .then((responseData) => {
    
                    // 拼接数据
                    this.data = this.data.concat(responseData.data);
    
                    // 重新渲染
                    this.setState({
                        dataSource: this.state.dataSource.cloneWithRows(this.data),
                        loaded:true,
                    });
    
                    // 存储数组中最后一个元素的id
                    let cnlastID = responseData.data[responseData.data.length - 1].id;
                    AsyncStorage.setItem('cnlastID', cnlastID.toString());  // 只能存储字符或字符串
    
                })
                .catch((error) => {
    
                })
        }
    
        // 加载更多数据操作
        loadMore() {
            // 读取存储的id
            AsyncStorage.getItem('cnlastID')
                .then((value) => {
                    // 数据加载操作
                    this.loadMoreData(value);
                })
        }
    
        // 模态到近半小时热门
        pushToHalfHourHot() {
            this.setState({
                isModal: true
            })
        }
    
        // 跳转到搜索页面
        pushToSearch() {
            this.props.navigator.push({
                component: Search,
            })
        }
    
        // 安卓模态销毁模态
        onRequestClose() {
            this.setState({
                isModal: false
            })
        }
    
        // 关闭模态
        closeModal(data) {
            this.setState({
                isModal:data
            })
        }
    
        // 返回左边按钮
        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尾部
        renderFooter() {
            return (
                <View style={{height: 100}}>
                    <ActivityIndicator />
                </View>
            );
        }
    
        // 根据网络状态决定是否渲染 listView
        renderListView() {
            if(this.state.loaded === false) {
                // 显示空白页
                return(
                    <NoDataView />
                );
            }else{
                return(
                    <PullList   // 将ListView 改为 PullList
                        // 下拉刷新
                        onPullRelease={(resolve) => this.loadData(resolve)}
                        // 数据源 通过判断dataSource是否有变化,来判断是否要重新渲染
                        dataSource={this.state.dataSource} 
                        renderRow={this.renderRow.bind(this)}
                        // 隐藏水平线
                        showsHorizontalScrollIndicator={false}
                        style={styles.listViewStyle}
                        initialListSize={5}
                        // 返回 listView 头部
                        renderHeader={this.renderHeader}
                        // 上拉加载更多
                        onEndReached={this.loadMore}
                        onEndReachedThreshold={60}
                        renderFooter={this.renderFooter}
                    />
                );
            }
        }
    
        // 通过id 跳转详情页
        pushToDetail(value) {
            this.props.navigator.push({
                component:CommunalDetail,
                params: {
                    url: 'https://guangdiu.com/api/showdetail.php' + '?' + 'id=' + value
                }
            })
        }
    
        // 返回每一行cell的样式
        renderRow(rowData) {
            // 使用cell组件
            return(
                <TouchableOpacity
                    // 给每一个cell添加点击事件
                    onPress={() => this.pushToDetail(rowData.id)}
                >
                    <CommunalHotCell
                        image={rowData.image}
                        title={rowData.title}
                    />
                </TouchableOpacity>
            );
        }
    
        // 生命周期 组件渲染完成 已经出现在dom文档里
        componentDidMount() {
            // 请求数据
            this.loadData();
        }
    
        render() {
            return (
                <View style={styles.container}>
                    {/* 初始化模态 */}
                    <Modal
                        animationType='slide'  // 动画 底部弹窗
                        transparent={false}  // 透明度
                        visible={this.state.isModal}  // 可见性
                        onRequestClose={() => this.onRequestClose()}  // 销毁
                    >
                        <Navigator
                            initialRoute={{
                                name:'halfHourHot',
                                component:HalfHourHot
                            }}
    
                            renderScene={(route, navigator) => {
                                let Component = route.component;
                                return <Component
                                    removeModal={(data) => this.closeModal(data)}
                                    {...route.params}
                                    navigator={navigator} />
                            }} />
                    </Modal>
    
                    {/* 导航栏样式 */}
                    <CommunalNavBar
                        leftItem = {() => this.renderLeftItem()}
                        titleItem = {() => this.renderTitleItem()}
                        rightItem = {() => this.renderRightItem()}
                    />
    
                    {/* 根据网络状态决定是否渲染 listView */}
                    {this.renderListView()}
                </View>
            );
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            alignItems: 'center',
        },
        navbarLeftItemStyle: {
            20,
            height:20,
            marginLeft:15,
        },
        navbarTitleItemStyle: {
            66,
            height:20,
        },
        navbarRightItemStyle: {
            20,
            height:20,
            marginRight:15,
        },
    
        listViewStyle: {
            width,
        },
    });

    核心代码:

    // 加载最新数据网络请求
        loadData(resolve) {
    
            let params = {"count" : 10 };
    
            HTTPBase.get('https://guangdiu.com/api/getlist.php', params)
                .then((responseData) => {
    
                    // 情况数组(刷新时)
                    this.data = [];
    
                    // 拼接数据
                    this.data = this.data.concat(responseData.data);
    
                    // 重新渲染
                    this.setState({
                        dataSource: this.state.dataSource.cloneWithRows(this.data),
                        loaded:true,
                    });
    
                    // 关闭刷新动画
                    if (resolve !== undefined){
                        setTimeout(() => {
                            resolve();
                        }, 1000);
                    }
    
                    // 存储数组中最后一个元素的id
                    let cnlastID = responseData.data[responseData.data.length - 1].id;
                    AsyncStorage.setItem('cnlastID', cnlastID.toString());  // 只能存储字符或字符串
    
                    // 首页存储数组中第一个元素的id
                    let cnfirstID = responseData.data[0].id;
                    AsyncStorage.setItem('cnfirstID', cnfirstID.toString());
    
                     // 清除本地存储的数据
                    RealmBase.removeAllData('HomeData');
    
                    // 存储数据到本地
                    RealmBase.create('HomeData', responseData.data); // 向数据表存储数据
                })
                .catch((error) => {
                    // 数据加载失败,拿到本地存储的数据,展示出来,如果没有存储,那就显示无数据页面
                    this.data = RealmBase.loadAll('HomeData'); // 从数据表提取数据
    
                    // 重新渲染
                    this.setState({
                        dataSource: this.state.dataSource.cloneWithRows(this.data),
                        loaded:true,
                    });
                })
        }
    

    2.因为 realm 下载的内容过大,不易上传至 github 需要在 .gitignore 上设置 忽略

    /node_modules/realm/*
    

    3.设置 ListView 默认显示条数,避免列表下出现空白

    4.自定义详情cell

    首先,还是一样,我们先来创建 GDCommunalCell 文件,并且我们将前面 自定义cell 里面的内容 copy 一下,放到这个文件中,并进行相应修改:

    GDCommunalCell.js

    /**
     * 公共 Cell
     */
    import React, { Component, PropTypes } from 'react';
    import {
        StyleSheet,
        Text,
        View,
        Dimensions,
        Platform,
        Image,
    } from 'react-native';
    
    // 获取屏幕宽高
    const {width, height} = Dimensions.get('window');
    
    export default class GDCommunalCell extends Component {
    
    	// 定义成员属性
    	static propTypes = {
            image:PropTypes.string,
            title:PropTypes.string,
            mall:PropTypes.string, // 平台
            pubTime:PropTypes.string, // 时间
            fromSite:PropTypes.string, // 来源
        };
    
        renderDate(pubTime, fromSite) {
    
            // 时间差的计算
            let minute = 1000 * 60;     // 1分钟
            let hour = minute * 60;     // 1小时
            let day = hour * 24;        // 1天
            let week = day * 7;         // 1周
            let month = day * 30;       // 1个月
    
            // 计算时间差
            let now = new Date().getTime();     // 获取当前时间
            let diffValue = now - Date.parse(pubTime.replace(/-/gi, "/"));
    
            if (diffValue < 0) return;
    
            let monthC = diffValue/month;   // 相差了几个月
            let weekC = diffValue/week;     // 相差几周
            let dayC = diffValue/day;       // 相差几天
            let hourC = diffValue/hour      // 相差几小时
            let minuteC = diffValue/minute; // 相差几分钟
    
            let result;
    
            if (monthC >= 1) {
                result = parseInt(monthC) + "月前";
            }else if (weekC >= 1) {
                result = parseInt(weekC) + "周前";
            }else if (dayC >= 1) {
                result = parseInt(dayC) + "天前";
            }else if (hourC >= 1) {
                result = parseInt(hourC) + "小时前";
            }else if (minuteC >= 1) {
                result = parseInt(minuteC) + "分钟前";
            }else result = "刚刚";
    
            return result + ' · ' + fromSite;
    
        }
    
        render() {
            return (
                <View style={styles.container}>
                    {/* 左边图片 */}
                    <Image source={{uri:this.props.image === '' ? 'defaullt_thumb_83x83' : this.props.image}} style={styles.imageStyle} />
                    {/* 中间 */}
                    <View style={styles.centerViewStyle}>
                        {/* 标题 */}
                        <View>
                            <Text numberOfLines={3} style={styles.titleStyle}>{this.props.title}</Text>
                        </View>
                        {/* 详情 */}
                        <View style={styles.detailViewStyle}>
                            {/* 平台 */}
                            <Text style={styles.detailMallStyle}>{this.props.mall}</Text>
                            {/* 时间 + 来源 */}
                            <Text style={styles.timeStyle}>{this.renderDate(this.props.pubTime, this.props.fromSite)}</Text>
                        </View>
    
                    </View>
                    {/* 右边的箭头 */}
                    <Image source={{uri:'icon_cell_rightArrow'}} style={styles.arrowStyle} />
                </View>
            );
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            flexDirection:'row',
            alignItems:'center',
            justifyContent:'space-between',
            backgroundColor:'white',
            height:100,
            width,
            borderBottomWidth:0.5,
            borderBottomColor:'gray',
            marginLeft:15
    
        },
    
        imageStyle: {
            70,
            height:70,
        },
    
        centerViewStyle: {
            height:70,
            justifyContent:'space-around',
        },
    
        titleStyle: {
            width * 0.65,
        },
    
        detailViewStyle: {
            flexDirection:'row',
            justifyContent:'space-between',
            alignItems:'center'
        },
        detailMallStyle: {
            fontSize:12,
            color:'green',
        },
        timeStyle: {
            fontSize:12,
            color:'gray',
        },
    
        arrowStyle: {
            10,
            height:10,
            marginRight:30,
        }
    });
    

    GDHome.js  及 GDHt.js 调用

    // 引入 公共cell
    import CommunalCell from '../main/GDCommunalCell';
    

    GDHome.js

    /**
     * 首页
     */
    import React, { Component } from 'react';
    import {
        StyleSheet,
        Text,
        View,
        TouchableOpacity,
        Image,
        ListView,
        Dimensions,
        ActivityIndicator,
        Modal, // 模态
        AsyncStorage, // 缓存数据库(数据持久化)
    } from 'react-native';
    
    // 引入 下拉刷新组件
    import {PullList} from 'react-native-pull';
    // 导航器
    import CustomerComponents, {
        Navigator
    } from 'react-native-deprecated-custom-components';
    
    // 获取屏幕宽高
    const {width, height} = Dimensions.get('window');
    
    // 引入自定义导航栏组件
    import CommunalNavBar from '../main/GDCommunalNavBar';
    // 引入 近半小时热门组件
    import HalfHourHot from './GDHalfHourHot';
    // 引入 搜索页面组件
    import Search from '../main/GDSearch';
    // 引入 公共cell
    import CommunalCell from '../main/GDCommunalCell';
    // 引入 详情页 组件
    import CommunalDetail from '../main/GDCommunalDetail';
    // 引入 空白页组件
    import NoDataView from '../main/GDNoDataView';
    
    export default class GDHome extends Component {
    
        // 构造
        constructor(props) {
            super(props);
            // 初始状态
            this.state = {
                dataSource: new ListView.DataSource({rowHasChanged:(r1, r2) => r1 !== r2}), // 数据源 优化
                loaded: false, // 用于判断是否显示空白页
                isModal: false, // 用于判断模态的可见性
            };
            // 全局定义一个空数组用于存储列表数据
            this.data = [];
            // 绑定
            this.loadData = this.loadData.bind(this);
            this.loadMore = this.loadMore.bind(this);
        }
    
        // 加载最新数据网络请求
        loadData(resolve) {
    
            let params = {"count" : 10 };
    
            HTTPBase.get('https://guangdiu.com/api/getlist.php', params)
                .then((responseData) => {
    
                    // 情况数组(刷新时)
                    this.data = [];
    
                    // 拼接数据
                    this.data = this.data.concat(responseData.data);
    
                    // 重新渲染
                    this.setState({
                        dataSource: this.state.dataSource.cloneWithRows(this.data),
                        loaded:true,
                    });
    
                    // 关闭刷新动画
                    if (resolve !== undefined){
                        setTimeout(() => {
                            resolve();
                        }, 1000);
                    }
    
                    // 存储数组中最后一个元素的id
                    let cnlastID = responseData.data[responseData.data.length - 1].id;
                    AsyncStorage.setItem('cnlastID', cnlastID.toString());  // 只能存储字符或字符串
    
                    // 首页存储数组中第一个元素的id
                    let cnfirstID = responseData.data[0].id;
                    AsyncStorage.setItem('cnfirstID', cnfirstID.toString());
    
                    // // 清除本地存储的数据
                    // RealmBase.removeAllData('HomeData');
    
                    // // 存储数据到本地
                    // RealmBase.create('HomeData', responseData.data); // 向数据表存储数据
                })
                .catch((error) => {
                    // // 数据加载失败,拿到本地存储的数据,展示出来,如果没有存储,那就显示无数据页面
                    // this.data = RealmBase.loadAll('HomeData'); // 从数据表提取数据
    
                    // // 重新渲染
                    // this.setState({
                    //     dataSource: this.state.dataSource.cloneWithRows(this.data),
                    //     loaded:true,
                    // });
                })
        }
    
        // 加载更多数据的网络请求
        loadMoreData(value) {
    
            let params = {
                "count" : 10,
                "sinceid" : value 
            };
    
            HTTPBase.get('https://guangdiu.com/api/getlist.php', params)
                .then((responseData) => {
    
                    // 拼接数据
                    this.data = this.data.concat(responseData.data);
    
                    // 重新渲染
                    this.setState({
                        dataSource: this.state.dataSource.cloneWithRows(this.data),
                        loaded:true,
                    });
    
                    // 存储数组中最后一个元素的id
                    let cnlastID = responseData.data[responseData.data.length - 1].id;
                    AsyncStorage.setItem('cnlastID', cnlastID.toString());  // 只能存储字符或字符串
    
                })
                .catch((error) => {
    
                })
        }
    
        // 加载更多数据操作
        loadMore() {
            // 读取存储的id
            AsyncStorage.getItem('cnlastID')
                .then((value) => {
                    // 数据加载操作
                    this.loadMoreData(value);
                })
        }
    
        // 模态到近半小时热门
        pushToHalfHourHot() {
            this.setState({
                isModal: true
            })
        }
    
        // 跳转到搜索页面
        pushToSearch() {
            this.props.navigator.push({
                component: Search,
            })
        }
    
        // 安卓模态销毁模态
        onRequestClose() {
            this.setState({
                isModal: false
            })
        }
    
        // 关闭模态
        closeModal(data) {
            this.setState({
                isModal:data
            })
        }
    
        // 返回左边按钮
        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尾部
        renderFooter() {
            return (
                <View style={{height: 100}}>
                    <ActivityIndicator />
                </View>
            );
        }
    
        // 根据网络状态决定是否渲染 listView
        renderListView() {
            if(this.state.loaded === false) {
                // 显示空白页
                return(
                    <NoDataView />
                );
            }else{
                return(
                    <PullList   // 将ListView 改为 PullList
                        // 下拉刷新
                        onPullRelease={(resolve) => this.loadData(resolve)}
                        // 数据源 通过判断dataSource是否有变化,来判断是否要重新渲染
                        dataSource={this.state.dataSource} 
                        renderRow={this.renderRow.bind(this)}
                        // 隐藏水平线
                        showsHorizontalScrollIndicator={false}
                        style={styles.listViewStyle}
                        initialListSize={7}  // 默认渲染数据条数
                        // 返回 listView 头部
                        renderHeader={this.renderHeader}
                        // 上拉加载更多
                        onEndReached={this.loadMore}
                        onEndReachedThreshold={60}
                        renderFooter={this.renderFooter}
                    />
                );
            }
        }
    
        // 通过id 跳转详情页
        pushToDetail(value) {
            this.props.navigator.push({
                component:CommunalDetail,
                params: {
                    url: 'https://guangdiu.com/api/showdetail.php' + '?' + 'id=' + value
                }
            })
        }
    
        // 返回每一行cell的样式
        renderRow(rowData) {
            // 使用cell组件
            return(
                <TouchableOpacity
                    // 给每一个cell添加点击事件
                    onPress={() => this.pushToDetail(rowData.id)}
                >
                    <CommunalCell
                        image={rowData.image}
                        title={rowData.title}
                        mall={rowData.mall}  // 平台
                        pubTime={rowData.pubtime}  // 时间
                        fromSite={rowData.fromsite}  // 来源
                    />
                </TouchableOpacity>
            );
        }
    
        // 生命周期 组件渲染完成 已经出现在dom文档里
        componentDidMount() {
            // 请求数据
            this.loadData();
        }
    
        render() {
            return (
                <View style={styles.container}>
                    {/* 初始化模态 */}
                    <Modal
                        animationType='slide'  // 动画 底部弹窗
                        transparent={false}  // 透明度
                        visible={this.state.isModal}  // 可见性
                        onRequestClose={() => this.onRequestClose()}  // 销毁
                    >
                        <Navigator
                            initialRoute={{
                                name:'halfHourHot',
                                component:HalfHourHot
                            }}
    
                            renderScene={(route, navigator) => {
                                let Component = route.component;
                                return <Component
                                    removeModal={(data) => this.closeModal(data)}
                                    {...route.params}
                                    navigator={navigator} />
                            }} />
                    </Modal>
    
                    {/* 导航栏样式 */}
                    <CommunalNavBar
                        leftItem = {() => this.renderLeftItem()}
                        titleItem = {() => this.renderTitleItem()}
                        rightItem = {() => this.renderRightItem()}
                    />
    
                    {/* 根据网络状态决定是否渲染 listView */}
                    {this.renderListView()}
                </View>
            );
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            alignItems: 'center',
        },
        navbarLeftItemStyle: {
            20,
            height:20,
            marginLeft:15,
        },
        navbarTitleItemStyle: {
            66,
            height:20,
        },
        navbarRightItemStyle: {
            20,
            height:20,
            marginRight:15,
        },
    
        listViewStyle: {
            width,
        },
    });
    

    GDHt.js

    /**
     * 海淘折扣
     */
    import React, { Component } from 'react';
    import {
        StyleSheet,
        Text,
        View,
        TouchableOpacity,
        Image,
        ListView,
        Dimensions,
        ActivityIndicator,
        Modal, // 模态
        AsyncStorage, // 缓存数据库(数据持久化)
    } from 'react-native';
    
    // 引入 下拉刷新组件
    import {PullList} from 'react-native-pull';
    // 导航器
    import CustomerComponents, {
        Navigator
    } from 'react-native-deprecated-custom-components';
    
    // 获取屏幕宽高
    const {width, height} = Dimensions.get('window');
    
    // 引入自定义导航栏组件
    import CommunalNavBar from '../main/GDCommunalNavBar';
    // 引入 近半小时热门组件
    import USHalfHourHot from './GDUSHalfHourHot';
    // 引入 搜索页面组件
    import Search from '../main/GDSearch';
    // 引入 cell
    import CommunalCell from '../main/GDCommunalCell';
    // 引入 详情页 组件
    import CommunalDetail from '../main/GDCommunalDetail';
    // 引入 空白页组件
    import NoDataView from '../main/GDNoDataView';
    
    export default class GDHome extends Component {
    
        // 构造
        constructor(props) {
            super(props);
            // 初始状态
            this.state = {
                dataSource: new ListView.DataSource({rowHasChanged:(r1, r2) => r1 !== r2}), // 数据源 优化
                loaded: false, // 用于判断是否显示空白页
                isModal: false, // 用于判断模态的可见性
            };
            // 全局定义一个空数组用于存储列表数据
            this.data = [];
            // 绑定
            this.loadData = this.loadData.bind(this);
            this.loadMore = this.loadMore.bind(this);
        }
    
        // 加载最新数据网络请求
        loadData(resolve) {
    
            let params = {
                "count" : 10,
                "country" : "us"
            };
    
            HTTPBase.get('https://guangdiu.com/api/getlist.php', params)
                .then((responseData) => {
    
                    // 清空数组(刷新时)
                    this.data = [];
    
                    // 拼接数据
                    this.data = this.data.concat(responseData.data);
    
                    // 重新渲染
                    this.setState({
                        dataSource: this.state.dataSource.cloneWithRows(this.data),
                        loaded:true,
                    });
    
                    // 关闭刷新动画
                    if (resolve !== undefined){
                        setTimeout(() => {
                            resolve();
                        }, 1000);
                    }
    
                    // 存储数组中最后一个元素的id
                    let uslastID = responseData.data[responseData.data.length - 1].id;
                    AsyncStorage.setItem('uslastID', uslastID.toString());  // 只能存储字符或字符串
    
                    // 首页存储数组中第一个元素的id
                    let usfirstID = responseData.data[0].id;
                    AsyncStorage.setItem('usfirstID', usfirstID.toString());
                    
                    // // 清除本地存储的数据
                    // RealmBase.removeAllData('HomeData');
    
                    // // 存储数据到本地
                    // RealmBase.create('HomeData', responseData.data); // 向数据表存储数据
                })
                .catch((error) => {
                    // // 数据加载失败,拿到本地存储的数据,展示出来,如果没有存储,那就显示无数据页面
                    // this.data = RealmBase.loadAll('HomeData'); // 从数据表提取数据
    
                    // // 重新渲染
                    // this.setState({
                    //     dataSource: this.state.dataSource.cloneWithRows(this.data),
                    //     loaded:true,
                    // });
                })
        }
    
        // 加载更多数据的网络请求
        loadMoreData(value) {
    
            let params = {
                "count" : 10,
                "country" : "us",
                "sinceid" : value 
            };
    
            HTTPBase.get('https://guangdiu.com/api/getlist.php', params)
                .then((responseData) => {
    
                    // 拼接数据
                    this.data = this.data.concat(responseData.data);
    
                    // 重新渲染
                    this.setState({
                        dataSource: this.state.dataSource.cloneWithRows(this.data),
                        loaded:true,
                    });
    
                    // 存储数组中最后一个元素的id
                    let uslastID = responseData.data[responseData.data.length - 1].id;
                    AsyncStorage.setItem('uslastID', uslastID.toString());  // 只能存储字符或字符串
    
                })
                .catch((error) => {
    
                })
        }
    
        // 加载更多数据操作
        loadMore() {
            // 读取存储的id
            AsyncStorage.getItem('uslastID')
                .then((value) => {
                    // 数据加载操作
                    this.loadMoreData(value);
                })
        }
    
        // 模态到近半小时热门
        pushToHalfHourHot() {
            this.setState({
                isModal: true
            })
        }
    
        // 跳转到搜索页面
        pushToSearch() {
            this.props.navigator.push({
                component: Search,
            })
        }
    
        // 安卓模态销毁模态
        onRequestClose() {
            this.setState({
                isModal: false
            })
        }
    
        // 关闭模态
        closeModal(data) {
            this.setState({
                isModal:data
            })
        }
    
        // 返回左边按钮
        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尾部
        renderFooter() {
            return (
                <View style={{height: 100}}>
                    <ActivityIndicator />
                </View>
            );
        }
    
        // 根据网络状态决定是否渲染 listView
        renderListView() {
            if(this.state.loaded === false) {
                // 显示空白页
                return(
                    <NoDataView />
                );
            }else{
                return(
                    <PullList   // 将ListView 改为 PullList
                        // 下拉刷新
                        onPullRelease={(resolve) => this.loadData(resolve)}
                        // 数据源 通过判断dataSource是否有变化,来判断是否要重新渲染
                        dataSource={this.state.dataSource} 
                        renderRow={this.renderRow.bind(this)}
                        // 隐藏水平线
                        showsHorizontalScrollIndicator={false}
                        style={styles.listViewStyle}
                        initialListSize={7}
                        // 返回 listView 头部
                        renderHeader={this.renderHeader}
                        // 上拉加载更多
                        onEndReached={this.loadMore}
                        onEndReachedThreshold={60}
                        renderFooter={this.renderFooter}
                    />
                );
            }
        }
    
        // 通过id 跳转详情页
        pushToDetail(value) {
            this.props.navigator.push({
                component:CommunalDetail,
                params: {
                    url: 'https://guangdiu.com/api/showdetail.php' + '?' + 'id=' + value
                }
            })
        }
    
        // 返回每一行cell的样式
        renderRow(rowData) {
            // 使用cell组件
            return(
                <TouchableOpacity
                    // 给每一个cell添加点击事件
                    onPress={() => this.pushToDetail(rowData.id)}
                >
                    <CommunalCell
                        image={rowData.image}
                        title={rowData.title}
                        mall={rowData.mall}  // 平台
                        pubTime={rowData.pubtime}  // 时间
                        fromSite={rowData.fromsite}  // 来源
                    />
                </TouchableOpacity>
            );
        }
    
        // 生命周期 组件渲染完成 已经出现在dom文档里
        componentDidMount() {
            // 请求数据
            this.loadData();
        }
    
        render() {
            return (
                <View style={styles.container}>
                    {/* 初始化模态 */}
                    <Modal
                        animationType='slide'  // 动画 底部弹窗
                        transparent={false}  // 透明度
                        visible={this.state.isModal}  // 可见性
                        onRequestClose={() => this.onRequestClose()}  // 销毁
                    >
                        <Navigator
                            initialRoute={{
                                name:'halfHourHot',
                                component:USHalfHourHot
                            }}
    
                            renderScene={(route, navigator) => {
                                let Component = route.component;
                                return <Component
                                    removeModal={(data) => this.closeModal(data)}
                                    {...route.params}
                                    navigator={navigator} />
                            }} />
                    </Modal>
    
                    {/* 导航栏样式 */}
                    <CommunalNavBar
                        leftItem = {() => this.renderLeftItem()}
                        titleItem = {() => this.renderTitleItem()}
                        rightItem = {() => this.renderRightItem()}
                    />
    
                    {/* 根据网络状态决定是否渲染 listView */}
                    {this.renderListView()}
                </View>
            );
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            alignItems: 'center',
        },
        navbarLeftItemStyle: {
            20,
            height:20,
            marginLeft:15,
        },
        navbarTitleItemStyle: {
            66,
            height:20,
        },
        navbarRightItemStyle: {
            20,
            height:20,
            marginRight:15,
        },
    
        listViewStyle: {
            width,
        },
    });
    

      

    .

  • 相关阅读:
    商务通代码
    Ubuntu 创建快捷方式的方法
    Linux安装Nginx
    Linux安装jdk10
    Mycat实现Mysql数据库读写分离
    Mysql主从复制
    SpringBoot整合Redis集群
    Redis集群环境搭建
    SpringBoot整合redis哨兵主从服务
    redis 哨兵机制环境搭建
  • 原文地址:https://www.cnblogs.com/crazycode2/p/7460282.html
Copyright © 2011-2022 走看看