React Native_手把手教你做项目(二.视频列表页布局&Mock虚拟数据)

我们继续在上一篇文章的基础上编写我们的应用程序,视频列表页List

我们先写垃圾代码,把整个的架子搭起来,然后如果有其他页面通用的组件的话,我们再进行封装处理

ListView布局

list.js文件

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

export default class list extends Component{
    constructor(props){
        super(props);
        this.state={
            dataSource:new ListView.DataSource({
                rowHasChanged:(r1,r2)=>r1!==r2,
            })
        }
    }

    componentDidMount() {
        //加载数据
        this.dsfetchData();
    }

    dsfetchData(){
        this.setState({
            dataSource:this.state.dataSource.cloneWithRows(['呵呵','哈哈','嘻嘻','嘿嘿','哎呦','不错哦'])
        })
    }

    render() {
        return (
            <View style={styles.container}>
                {/*导航条*/}
                <View style={styles.header}>
                    <Text style={styles.headerText}>
                        视频列表
                    </Text>
                </View>
                {/*列表页面*/}
                <ListView
                    dataSource={this.state.dataSource}
                    renderRow={this._renderRow}
                    style={styles.listView}
                />
            </View>
        );
    }

    //下划线代表内部类自己用的函数,属于规范
    _renderRow=(rowData)=>{
        return (
            <Text>{rowData}</Text>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#F5FCFF',
    },
    header:{
        // marginTop:Platform.OS == 'ios'?20:0,
        paddingTop:25,
        paddingBottom:15,
        backgroundColor:'#dddddd',
        borderBottomWidth:0.5,
        borderBottomColor:'black',
    },
    headerText:{
        fontWeight:'600',
        textAlign:'center',
        fontSize: 16,
    },
    listView:{

    }
});

这里写图片描述

Mock模拟数据

Mock模拟数据

  1. 列表内容
    Web应用前后端(台)分离:
    后台向前台提供API接口,只负责数据的提供和计算,而完全不处理展现
    前台通过Http(Ajax)请求获取数据, 在浏览器端动态构建界面显示数据

  2. 设计JSON数据结构

  3. 利用Node+express提供模拟数据
    优点:可以在浏览器端访问
    缺点:如果是打包发布就无法访问模拟数据, 只能是测试时使用

RAP
RAP是一个可视化接口管理工具 通过分析接口结构,动态生成模拟数据,校验真实接口正确性, 围绕接口定义,通过一系列自动化工具提升我们的协作效率。我们的口号:提高效率,回家吃晚饭!

首先在RAP上面注册账号,添加团队,添加项目
这里写图片描述

这里写图片描述

注意这里的备注的@cparagraph(1, 3)是在Mock中寻找的

这里写图片描述

这里写图片描述

完善模拟接口
这里写图片描述

设置完成后,点击
这里写图片描述

这里写图片描述

把生成的数据先复制到DataSource中,进行简单的页面布局

list.js

import React, { Component } from 'react';
import {
    Platform,
    StyleSheet,
    Text,
    View,
    ListView,
    TouchableOpacity,
    Image
} from 'react-native';

import Icon from 'react-native-vector-icons/Ionicons';
import Dimensions from 'Dimensions';

const {width, height} = Dimensions.get('window');

export default class list extends Component{
    constructor(props){
        super(props);
        this.state={
            dataSource:new ListView.DataSource({
                rowHasChanged:(r1,r2)=>r1!==r2,
            })
        }
    }

    componentDidMount() {
        //加载数据
        this.dsfetchData();
    }

    dsfetchData(){
        this.setState({
            dataSource:this.state.dataSource.cloneWithRows([ {
                "_id":"630000201107028547","thumb":"http://dummyimage.com/1024x700/2026c9,图片上的文字)","title":"@cparagraph(1, 3)","video":"'http://v.youku.com/v_show/id_XMzY5ODY5MDI3Ng==.html?spm=a2h1n.8251846.0.0'"
            }
                ,
                {
                    "_id":"350000201510184550","thumb":"http://dummyimage.com/1024x700/e3bdd2,图片上的文字)","title":"@cparagraph(1, 3)","video":"'http://v.youku.com/v_show/id_XMzY5ODY5MDI3Ng==.html?spm=a2h1n.8251846.0.0'"
                }
                ,
                {
                    "_id":"130000199211104265","thumb":"http://dummyimage.com/1024x700/a242ec,图片上的文字)","title":"@cparagraph(1, 3)","video":"'http://v.youku.com/v_show/id_XMzY5ODY5MDI3Ng==.html?spm=a2h1n.8251846.0.0'"
                }])
        })
    }

    render() {
        return (
            <View style={styles.container}>
                {/*导航条*/}
                <View style={styles.header}>
                    <Text style={styles.headerText}>
                        视频列表
                    </Text>
                </View>
                {/*列表页面*/}
                <ListView
                    dataSource={this.state.dataSource}
                    renderRow={this._renderRow}
                    style={styles.listView}
                />
            </View>
        );
    }

    //下划线代表内部类自己用的函数,属于规范
    _renderRow=(rowData)=>{
        return (
            <TouchableOpacity>

                {/*整个Cell*/}
                <View style={styles.cellStyle}>
                    {/*标题文字*/}
                    <Text style={styles.title}>{rowData.title}</Text>


                    <Image style={styles.thumb} source={{uri:rowData.thumb}} >

                    </Image>
                    <Icon name="ios-play"
                          size={30}
                          style={styles.play}
                    />
                    {/*点赞&评论*/}
                    <View style={styles.cellFooter}>
                        {/*点赞*/}
                        <View style={styles.footerBox}>
                            <Icon name="ios-heart-outline"
                                  size={30}
                                  style={styles.boxIcon}
                            />
                            {/*点赞文字*/}
                            <Text style={styles.boxText}>点赞</Text>
                        </View>

                        {/*评论*/}
                        <View style={styles.footerBox}>
                            <Icon name="ios-chatbubbles-outline"
                                  size={30}
                                  style={styles.boxIcon}
                            />
                            {/*点赞文字*/}
                            <Text style={styles.boxText}>评论</Text>
                        </View>
                    </View>
                </View>
            </TouchableOpacity>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#F5FCFF',
    },
    header:{
        // marginTop:Platform.OS == 'ios'?20:0,
        paddingTop:25,
        paddingBottom:15,
        backgroundColor:'#dddddd',
        borderBottomWidth:0.5,
        borderBottomColor:'black',
    },
    headerText:{
        fontWeight:'600',
        textAlign:'center',
        fontSize: 16,
    },
    listView:{

    },
    cellStyle:{
        width:width,
        marginTop:10,
        backgroundColor:'white',

    },
    title:{
        padding:10,
        color:'black',
        fontSize:18
    },
    thumb:{
        width:width,
        height:width*0.56,
        resizeMode:'cover'
    },
    play:{
        position:'absolute',
        bottom:100,
        right:14,
        width:46,
        height:46,
        paddingTop:8,
        paddingLeft:18,
        backgroundColor:'transparent',
        borderColor:'black',
        borderWidth:0.5,
        borderRadius:23,
    },
    cellFooter:{
        flexDirection:'row',
        justifyContent:'space-between',
        backgroundColor:'#dddddd',
    },
    footerBox:{
        padding:10,
        flexDirection:'row',
        backgroundColor:'white',
        flex:1,
        marginLeft:1,
        justifyContent:'center',

    },
    boxIcon:{
        fontSize:22,
        color:'#333',
    },
    boxText:{
        fontSize:18,
        color:'#333',
        paddingLeft:12,
        marginTop:2
    }
});

效果图:

这里写图片描述

请求mock数据

安装工具Mock.js

npm i mockjs –save

list.js

import React, { Component } from 'react';
import {
    Platform,
    StyleSheet,
    Text,
    View,
    ListView,
    TouchableOpacity,
    Image
} from 'react-native';

import Icon from 'react-native-vector-icons/Ionicons';
import Dimensions from 'Dimensions';

const {width, height} = Dimensions.get('window');

// Mockjs 解析随机的文字
import  Mock from 'mockjs';

export default class list extends Component{
    constructor(props){
        super(props);
        this.state={
            dataSource:new ListView.DataSource({
                rowHasChanged:(r1,r2)=>r1!==r2,
            }),
            url:'http://rap.taobao.org/mockjs/35294/api/list?accessToken=001'
        }
    }

    //即将显示
    componentWillMount() {
        //加载本地数据
        // this.dsfetchData();
    }
    componentDidMount() {
        //加载网络数据
        this._fetchData();
    }

    _fetchData(){
        fetch(this.state.url).then(
            (response) => {
                return response.json()
            }
        ).then(
            (response) => {

                let result = Mock.mock(response);
                console.log('服务器返回的数据是'+result);
                //先判断有没有数据
                    if(result.success) {
                        this.setState({
                            dataSource:this.state.dataSource.cloneWithRows(result.data)
                        })
                    }
            }
        )
    }

    dsfetchData(){
        let result = Mock.mock({
            "data|20":
                [
                    {
                        "_id":
                            "@ID",
                        "thumb":
                            "@IMG(1024x700,@COLOR(),\'\u56fe\u7247\u4e0a\u7684\u6587\u5b57\')",
                        "title":
                            "@cparagraph(1, 3)",
                        "video":
                            "\'http:\/\/v.youku.com\/v_show\/id_XMzY5ODY5MDI3Ng==.html?spm=a2h1n.8251846.0.0\'"
                    }
                ],
            "success": true
        })
        this.setState({
            dataSource:this.state.dataSource.cloneWithRows(result.data)
        })
    }

    render() {
        return (
            <View style={styles.container}>
                {/*导航条*/}
                <View style={styles.header}>
                    <Text style={styles.headerText}>
                        视频列表
                    </Text>
                </View>
                {/*列表页面*/}
                <ListView
                    dataSource={this.state.dataSource}
                    renderRow={this._renderRow}
                    style={styles.listView}
                />
            </View>
        );
    }

    //下划线代表内部类自己用的函数,属于规范
    _renderRow=(rowData)=>{
        return (
            <TouchableOpacity>

                {/*整个Cell*/}
                <View style={styles.cellStyle}>
                    {/*标题文字*/}
                    <Text style={styles.title}>{rowData.title}</Text>


                    <Image style={styles.thumb} source={{uri:rowData.thumb}} >

                    </Image>
                    <Icon name="ios-play"
                          size={30}
                          style={styles.play}
                    />
                    {/*点赞&评论*/}
                    <View style={styles.cellFooter}>
                        {/*点赞*/}
                        <View style={styles.footerBox}>
                            <Icon name="ios-heart-outline"
                                  size={30}
                                  style={styles.boxIcon}
                            />
                            {/*点赞文字*/}
                            <Text style={styles.boxText}>点赞</Text>
                        </View>

                        {/*评论*/}
                        <View style={styles.footerBox}>
                            <Icon name="ios-chatbubbles-outline"
                                  size={30}
                                  style={styles.boxIcon}
                            />
                            {/*点赞文字*/}
                            <Text style={styles.boxText}>评论</Text>
                        </View>
                    </View>
                </View>
            </TouchableOpacity>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#F5FCFF',
    },
    header:{
        // marginTop:Platform.OS == 'ios'?20:0,
        paddingTop:25,
        paddingBottom:15,
        backgroundColor:'#dddddd',
        borderBottomWidth:0.5,
        borderBottomColor:'black',
    },
    headerText:{
        fontWeight:'600',
        textAlign:'center',
        fontSize: 16,
    },
    listView:{

    },
    cellStyle:{
        width:width,
        marginTop:10,
        backgroundColor:'white',

    },
    title:{
        padding:10,
        color:'black',
        fontSize:18
    },
    thumb:{
        width:width,
        height:width*0.56,
        resizeMode:'cover'
    },
    play:{
        position:'absolute',
        bottom:100,
        right:14,
        width:46,
        height:46,
        paddingTop:8,
        paddingLeft:18,
        backgroundColor:'transparent',
        borderColor:'black',
        borderWidth:0.5,
        borderRadius:23,
    },
    cellFooter:{
        flexDirection:'row',
        justifyContent:'space-between',
        backgroundColor:'#dddddd',
    },
    footerBox:{
        padding:10,
        flexDirection:'row',
        backgroundColor:'white',
        flex:1,
        marginLeft:1,
        justifyContent:'center',

    },
    boxIcon:{
        fontSize:22,
        color:'#333',
    },
    boxText:{
        fontSize:18,
        color:'#333',
        paddingLeft:12,
        marginTop:2
    }
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值