【React Native入门系列文章 六】实战写一个电影列表页


React Native入门系列文章

第一篇:《小白扫盲篇

第二篇:《如何编写样式

第三篇:《如何手动开始写一个组件

第四篇:《组件间通信

第五篇:《踩过的坑

第六篇:《实战写一个电影列表页

第七篇:《网络通信和缓存处理

第八篇:《Android打包发布

第九篇:《如何从零开始学redux

这一节介绍,如何用React Native实现一个电影列表页。主要目的就是,熟悉React Native基本语法。

一、先看下要做成什么样子

这里涉及到的知识点主要就是:1、熟悉FlatList控件使用规则;2、熟悉styles属性;3、熟悉React Native基本语法规则。

二、FlatList控件使用

		<FlatList
                    style={styles.row}
                    numColumns={3}
                    keyExtractor={item => item.id}
                    data={movies.subjects}
                    renderItem={
                        ({item}) =>
                    <Item
                    	title={item.title}
                    	image={item.images.medium}
                    	stars={item.rating.stars}/>
                    }
                />

FlatList跟其他控件类似,可以通过设置styles属性来控制样式,numColumns指定一共有多少列,keyExtractor指定每一项的id,data指定数据源,renderItem用来为每一个Item设置参数。

其中,Item为自定义的控件。以下为Item.js的源码:

import React, {Component} from 'react';
import {
    StyleSheet,
    View,
    AppRegistry,
    Text,
    Image,
    Dimensions,
} from 'react-native';
 
const {width, height} = Dimensions.get('window');
 
const thirdWidth = width / 3;
 
const imageWidth = thirdWidth - 10 * 2;
const imageHeight = imageWidth / 0.697
 
export default class Item extends Component {
    render() {
        const {title, image, stars} = this.props;
        return (
            <View style={styles.root}>
                <Image source={{uri:image}}
                       style={styles.image}/>
                <Text style={styles.title} numberOfLines={1}>{title}</Text>
                {renderStars(stars)}
            </View>
        );
    }
}
 
const renderStars = (stars) => {
    const total = 5;
    let full, half, empty;
    full = stars[0];
    if (stars[1] === '5') {
        full++;
        half = 0;
        empty = total - full;
    } else {
        half = 1;
        empty = total - full - half;
    }
    const results = [];
    let i;
    for (i = 0; i < full; i++) {
        results.push(
            <Image
                key={i}
                style={styles.stars}
                source={require("../img/star-full.png")}
            />);
    }
    if (half) {
        results.push(
            <Image
                key={i}
                style={styles.stars}
                source={require("../img/star-half.png")}
            />);
        i++;
    }
    for (let j = 0; j < empty; j++) {
        results.push(
            <Image
                key={i+j}
                style={styles.stars}
                source={require("../img/star-empty.png")}
            />);
    }
    return (
        <View style={styles.starsWrapper}>
            {results}
        </View>
    );
}
 
const styles = StyleSheet.create({
    root: {
        width: imageWidth,
        marginRight: 15,
        marginTop: 20,
    },
    image: {
        height: imageHeight,
        width: imageWidth,
    },
    title: {
        fontSize: 20,
        fontWeight: 'bold',
        textAlign: 'center',
    },
    starsWrapper: {
        flexDirection: 'row',
    },
    stars: {
        width: 10,
        height: 10
    }
});

三、熟悉styles属性:

该电影列表的布局思路如下:

1、首先给FlatList加一个paddingHorizontal属性,使得FlatList左右空出15;

2、设置图片宽度为屏幕宽度-4*间隔,设置图片高度为宽度的1.3倍;

const {width, height} = Dimensions.get('window');
 
const thirdWidth = width / 3;
 
const imageWidth = thirdWidth - 10 * 2;
const imageHeight = imageWidth / 0.697

在styles里把imageWidth和imageHeight赋值给height和width就行了。

3、给Item设置marginTop;给Text设置一行显示,api为numberOfLines;

四、熟悉React Native基本语法

1、定义控件的两种方式:

(1)函数法:

const renderStars = (stars) => {
    const total = 5;
    let full, half, empty;
    full = stars[0];
    if (stars[1] === '5') {
        full++;
        half = 0;
        empty = total - full;
    } else {
        half = 1;
        empty = total - full - half;
    }
    const results = [];
    let i;
    for (i = 0; i < full; i++) {
        results.push(
            <Image
                key={i}
                style={styles.stars}
                source={require("../img/star-full.png")}
            />);
    }
    if (half) {
        results.push(
            <Image
                key={i}
                style={styles.stars}
                source={require("../img/star-half.png")}
            />);
        i++;
    }
    for (let j = 0; j < empty; j++) {
        results.push(
            <Image
                key={i+j}
                style={styles.stars}
                source={require("../img/star-empty.png")}
            />);
    }
    return (
        <View style={styles.starsWrapper}>
            {results}
        </View>
    );
}

这个方法返回值为“星星评分”,使用时,只需要在render方法里:{renderStars(stars)}就可以了。

(2)组件法:

export default class App extends Component {
    render() {
        return (
            <View>
                <FlatList
                    style={styles.row}
                    numColumns={3}
                    keyExtractor={item => item.id}
                    data={movies.subjects}
                    renderItem={
                        ({item}) =>
                    <Item
                    title={item.title}
                    image={item.images.medium}
                    stars={item.rating.stars}/>
                    }
                />
            </View>
 
        );
    }
}

 

五、React Native中文网主推的页面跳转方式(React Navigation)

它的使用非常简单:

1、安装导航库:npm install --save react-navigation

2、引入 import {StackNavigator}  from 'react-navigation';

3、StackNavigator的声明:

const App = StackNavigator({
    List: {screen: List},
    Detail: {screen: Detail},
});

以上代码就可完成路由的配置,可以看到我一共配置了两个页面。一个是产品列表页List.js,另一个是产品详情页Detail.js。

假设页面A要调到页面B,B再回退到A。

一、如何页面跳转?

1、从props中取出navigation的navigate方法(只要把组件加入到StackNavigator中,就会自动传入props);

const {navigate} = this.props.navigation;

2、通过navigate方法跳转

            <View>
                <FlatList
                    style={styles.row}
                    numColumns={3}
                    keyExtractor={item => item.id}
                    onRefresh={this.fetchdata}
                    refreshing={refreshing}
                    data={movies}
                    renderItem={
                 ({item}) =>
                 <Item
                 title={item.title}
                 image={item.images.medium}
                 stars={item.rating.stars}
                 onPress={() => navigate('Detail',{
                     id: item.id,
                 })}/>
                 }
                />
            </View>

3、通过navigate回退

(1)取出navigation的goBack方法

const {goBack} = this.props.navigation;

(2)调用goBack方法

            <View>
                <Text>电影详情页</Text>
                <Text>电影id:{state.params.id}</Text>
                <Text onPress={() => goBack()}>返回</Text>
            </View>

二、页面跳转如何传参?

1、B如何接收值?

const {state} = this.props.navigation;

从navigation中取出state值,这个值就是页面跳转传过来的值

2、A如何收到B回退传过来的值?

(1)在A中定义一个callback方法,并且把callback方法传给B

a)在state中加一个childState

    state = {
        movies: movies.subjects,
        refreshing: false,
        childState: '',
    };

b)在render中取出childState

const {movies, refreshing, childState} = this.state;

c)定义一个callback方法,在callback中setState

<View>
                <Text>子组件返回的数据:{childState}</Text>
                <FlatList
                    style={styles.row}
                    numColumns={3}
                    keyExtractor={item => item.id}
                    onRefresh={this.fetchdata}
                    refreshing={refreshing}
                    data={movies}
                    renderItem={
                 ({item}) =>
                 <Item
                 title={item.title}
                 image={item.images.medium}
                 stars={item.rating.stars}
                 onPress={() => navigate('Detail',{
                     id: item.id,
                     callback: (data) => {
                         this.setState({
                             childState: data
                         })
                     }
                 })}/>
                 }
                />
            </View>
callback: (data) => {
                         this.setState({
                             childState: data
                         })
                     }
                 })}/>
                 }
                />
            </View>

(2)在B中传值

a)从navigation中取出state值

const {state, goBack} = this.props.navigation;

b)通过state的callback方法回调

return (
            <View>
                <Text>电影详情页</Text>
                <Text>电影id:{state.params.id}</Text>
                <Text onPress={() => {
                    state.params.callback("test");
                    goBack();
                }}>返回</Text>
            </View>

        );
return (
            <View>
                <Text>电影详情页</Text>
                <Text>电影id:{state.params.id}</Text>
                <Text onPress={() => {
                    state.params.callback("test");
                    goBack();
                }}>返回</Text>
            </View>

        );

六、总结

本文学习了React Native实战电影列表页,以及页面跳转间参数传递。

此处为demo地址,欢迎star,后续会持续更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值