ReactNative学习笔记(五)之ListView

栏目: IOS · Android · 发布时间: 6年前

内容简介:接上一篇ListView就是列表视图, 一个用来显示垂直滚动的内容列表.它需要两个东西, dataSource, 就是数据源.和renderRow, 用来显示每一行内容用的模板.首先导入ListView

接上一篇 ReactNative学习笔记(四)之自定义文本组件与Image组件 继续学习ReactNative

ListView

ListView就是列表视图, 一个用来显示垂直滚动的内容列表.它需要两个东西, dataSource, 就是数据源.和renderRow, 用来显示每一行内容用的模板.

首先导入ListView

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

然后在App这个类中添加一个constructor方法

export default class App extends Component<Props> {
    constructor(props) {
        super(props)
        let movies = [
            {'title': '肖申克的救赎'},
            {'title': '这个杀手不太冷'},
            {'title': '阿甘正传'},
            {'title': '霸王别姬'},
            {'title': '美丽人生'},
            {'title': '三傻大闹宝莱坞'},
            {'title': '触不可及'},
            {'title': '时空恋旅人'},
            {'title': '我和狗狗的十个约定'},
        ];

        let dataSource = new ListView.DataSource({
            rowHasChanged: (row1, row2) => row1 !== row2
        });

        this.state = {
            movies: dataSource.cloneWithRows(movies)
        };
    }
    ...
}

constructor方法里需要先调用super(props)方法. 我们手工添加一些数据.ListView本身有一种很有效的方法去显示列表的数据, 而且我们要确定重新显示列表内容的时候只重新显示修改过的数据, 所以需要一个对比数据的方法, 也就是rowHasChanged方法.

再去设置组件初始化的状态, 把这个状态作为ListView的数据源.

然后我们再修改App的render方法

export default class App extends Component<Props> {
    ...
    render() {
        return (
            <View
                style={styles.container}>
                <ListView
                    dataSource={this.state.movies}
                    renderRow={
                        movie => <Text style={styles.itemText}>{movie.title}</Text>
                    }
                />
            </View>
        );
    }
}

运行效果:

ReactNative学习笔记(五)之ListView

从网络获取数据并重新整理列表的显示

首先需要从网络请求数据, 我们使用的api是这个 https://api.douban.com/v2/movie/top250 , 在App这个类里面写一个fetchData方法

fetchData() {
    fetch(REQUEST_URL)
        .then(response => response.json())
        .then(responseData => {
            this.setState({
                movies: this.state.movies.cloneWithRows(responseData.subjects),
                loaded: true
            })
        })
        .done();
}

对了, App的构造函数的的state中需要加一个loaded变量, 用来标记数据是否已经加载完成.在fetchData方法中, 先将数据转json, 然后我们使用的数据是subjects这部分数据作为数据源

ReactNative学习笔记(五)之ListView

在得到数据之后将state中的loaded属性设置为true.

然后我们修改App的render方法

render() {
    if(!this.state.loaded) {
        return (
            <View style={styles.container}>
                <View style={styles.loading}>
                    <Text>加载中...</Text>
                </View>

            </View>
        );
    }
    return (
        <View style={styles.container}>
            <ListView
                dataSource={this.state.movies}
                renderRow={this.renderMovieList}
            />
        </View>
    );
}

在state为false的时候显示一个加载中的视图, 如果state为true, 那就显示一个ListView, 数据源就是this.state中的movies, 模板就是一个renderMovieList方法

renderMovieList(movie) {
    return (
        <View style={styles.item}>
            <View style={styles.itemImage}>
                <Image
                    source={{uri: movie.images.large}}
                    style={styles.image}
                />
            </View>
            <View style={styles.itemContent}>
                <Text style={styles.itemHeader}>{movie.title}</Text>
                <Text style={styles.itemMeta}>
                    {movie.original_title} ( {movie.year} )
                </Text>
                <Text style={styles.redText}>
                    {movie.rating.average}
                </Text>

            </View>
        </View>
    )
}

这里的样式经过整理了一下, 稍微有些繁琐, 代码如下:

let styles = StyleSheet.create({
    redText: {
        color: '#db2828',
        fontSize: 15,
    },
    itemMeta: {
        fontSize: 16,
        color: 'rgba(0, 0, 0, 0.6)',
        marginBottom: 6,
    },
    itemHeader: {
        fontSize: 18,
        fontFamily: 'Helvetica Neue',
        fontWeight: '300',
        color: '#6435c9',
        marginBottom: 6,
    },
    itemContent: {
        flex: 1,  // todo 这里的flex等于1到底有什么用
        marginLeft: 13,
        marginTop: 6,
    },
    item: {
        flexDirection: 'row',
        borderBottomWidth: 1,
        borderColor: 'rgba(100, 53, 201, 0.1)',
        paddingBottom: 6,
        marginBottom: 6,
        flex: 1, //
    },
    loading: {
        flex: 1,  // todo 这里的flex等于1到底有什么用
        justifyContent: 'center',
        alignItems: 'center',
    },
    ...
});

运行效果:

ReactNative学习笔记(五)之ListView

注意如果把itemContent属性中的flex: 1注释掉, flex属性就会变成默认的stretch

效果如下:

ReactNative学习笔记(五)之ListView

可以看到文字跑到外面去了, 这是因为, stretch是伸展、张开的意思, 如果文字太长就会将容纳文字的容器的宽度撑大, 也就是Android里的包裹内容的意思, 一撑就撑到屏幕外面去了, 而如果限制容器的宽度为剩余空间的宽度, 文字就会在到控件边缘的时候自动换行了, 不会超出控件的宽度.这点需要注意.


以上所述就是小编给大家介绍的《ReactNative学习笔记(五)之ListView》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Charlotte's Web

Charlotte's Web

E. B. White / Scholastic / 2004 / USD 0.01

This is the tale of how a little girl named Ferm, with the help of a friendly spider, saved her pig, Wilbur, from the usual fate of nice fat little pigs.一起来看看 《Charlotte's Web》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

在线进制转换器
在线进制转换器

各进制数互转换器

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码