React Native ListView 信息总结

在 React Native 中,ListView 组件是非常常用的一个组件。它用于展示大量的数据项,支持滚动、下拉刷新、上拉加载等功能,在 App 开发中的作用不可替代。本文将对 React Native ListView 进行总结和梳理,旨在帮助开发者更好地理解和使用这个组件。

基本用法

ListView 最基本的用法就是列表展示数据。我们可以通过设置数据源和渲染子组件来实现。例如下面这个例子展示了如何使用 ListView 显示一个简单的列表:

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

export default class MyListView extends Component {
  constructor(props) {
    super(props);

    this.state = {
      dataSource: new ListView.DataSource({
        rowHasChanged: (r1, r2) => r1 !== r2,
      }),
    };
  }

  componentDidMount() {
    const data = [
      { name: '张三', age: 18 },
      { name: '李四', age: 20 },
      { name: '王五', age: 22 },
    ];
    this.setState({
      dataSource: this.state.dataSource.cloneWithRows(data),
    });
  }

  render() {
    return (
      <ListView
        dataSource={this.state.dataSource}
        renderRow={(rowData) => (
          <View>
            <Text>{rowData.name}</Text>
            <Text>{rowData.age}</Text>
          </View>
        )}
      />
    );
  }
}

AppRegistry.registerComponent('MyListView', () => MyListView);

值得注意的是,在构造函数中我们设置了 dataSource,它是通过 ListView.DataSource 的一个实例来创建的。对于每一行的数据,我们需要判断它是否是相同的,这里通过 rowHasChanged 函数来实现。在 componentDidMount 生命周期方法中,我们将数据源设置为 ListView 的 dataSource 属性,并调用 cloneWithRows 方法将数据传入。

在 render 方法中,我们通过 renderRow 属性来指定每一行的渲染方式。这里我们使用了一个简单的 View 和 Text 来显示一条数据。

横向滚动

ListView 默认是纵向滚动的,如果我们需要横向滚动,可以设置 horizontal 属性为 true。例如:

<ListView
  horizontal={true}
  ...
/>

下拉刷新

当我们需要下拉刷新列表的时候,可以使用 RefreshControl 组件。RefreshControl 是一个内置的组件,具有下拉刷新的功能。例如:

import React, { Component } from 'react';
import { AppRegistry, ListView, Text, View, RefreshControl } from 'react-native';

export default class MyListView extends Component {
  constructor(props) {
    super(props);

    this.state = {
      dataSource: new ListView.DataSource({
        rowHasChanged: (r1, r2) => r1 !== r2,
      }),
      refreshing: false,
    };
  }

  componentDidMount() {
    const data = [
      { name: '张三', age: 18 },
      { name: '李四', age: 20 },
      { name: '王五', age: 22 },
    ];
    this.setState({
      dataSource: this.state.dataSource.cloneWithRows(data),
    });
  }

  _onRefresh() {
    this.setState({ refreshing: true });
    setTimeout(() => {
      const data = [
        { name: '张三', age: 18 },
        { name: '李四', age: 20 },
        { name: '王五', age: 22 },
        { name: '赵六', age: 24 },
        { name: '钱七', age: 26 },
      ];
      this.setState({
        dataSource: this.state.dataSource.cloneWithRows(data),
        refreshing: false,
      });
    }, 2000);
  }

  render() {
    return (
      <ListView
        dataSource={this.state.dataSource}
        renderRow={(rowData) => (
          <View>
            <Text>{rowData.name}</Text>
            <Text>{rowData.age}</Text>
          </View>
        )}
        refreshControl={
          <RefreshControl
            refreshing={this.state.refreshing}
            onRefresh={this._onRefresh.bind(this)}
          />
        }
      />
    );
  }
}

AppRegistry.registerComponent('MyListView', () => MyListView);

在这个例子中,我们新增了一个 refreshing 状态,用于标记是否正在刷新数据。在 _onRefresh 方法中,我们将 refreshing 置为 true,模拟开始刷新数据;2 秒后,我们随机生成 5 条新的数据,并将 refreshing 置为 false,标记刷新结束。

在 ListView 的属性中,我们新增了一个 refreshControl,它可以用来指定 RefreshControl 的一些属性,如 refreshing 和 onRefresh 等。

上拉加载

和下拉刷新类似,当需要在 ListView 中添加上拉加载更多的功能时,我们可以使用 onEndReached 属性和 onEndReachedThreshold 等属性来实现。例如:

import React, { Component } from 'react';
import { AppRegistry, ListView, Text, View, RefreshControl } from 'react-native';

export default class MyListView extends Component {
  constructor(props) {
    super(props);

    this.state = {
      dataSource: new ListView.DataSource({
        rowHasChanged: (r1, r2) => r1 !== r2,
      }),
      refreshing: false,
      hasMore: true,
      data: [
        { name: '张三', age: 18 },
        { name: '李四', age: 20 },
        { name: '王五', age: 22 },
      ],
    };
  }

  _onRefresh() {
    this.setState({ refreshing: true });
    setTimeout(() => {
      const data = [
        { name: '张三', age: 18 },
        { name: '李四', age: 20 },
        { name: '王五', age: 22 },
      ];
      this.setState({
        dataSource: this.state.dataSource.cloneWithRows(data),
        refreshing: false,
        hasMore: true,
        data: data,
      });
    }, 2000);
  }

  _loadMore() {
    if (!this.state.hasMore) {
      return;
    }

    // 模拟异步获取数据
    setTimeout(() => {
      const data = [
        { name: '赵六', age: 24 },
        { name: '钱七', age: 26 },
      ];

      const newData = this.state.data.concat(data);
      const hasMore = newData.length < 11 ? true : false;

      this.setState({
        dataSource: this.state.dataSource.cloneWithRows(newData),
        hasMore: hasMore,
        data: newData,
      });
    }, 2000);
  }

  renderFooter() {
    if (!this.state.hasMore) {
      return (
        <View style={{ alignItems: 'center', paddingVertical: 10 }}>
          <Text style={{ color: '#ccc' }}>没有更多了~</Text>
        </View>
      );
    }
    return null;
  }

  render() {
    return (
      <ListView
        dataSource={this.state.dataSource}
        renderRow={(rowData) => (
          <View>
            <Text>{rowData.name}</Text>
            <Text>{rowData.age}</Text>
          </View>
        )}
        refreshControl={
          <RefreshControl
            refreshing={this.state.refreshing}
            onRefresh={this._onRefresh.bind(this)}
          />
        }
        onEndReached={this._loadMore.bind(this)}
        onEndReachedThreshold={10}
        renderFooter={this.renderFooter.bind(this)}
      />
    );
  }
}

AppRegistry.registerComponent('MyListView', () => MyListView);

在这个例子中,我们新增了一个 hasMore 状态,用于标记是否还有更多数据可供加载。在 _loadMore 方法中,我们模拟异步获取数据,并将新数据通过 concat 方法和原始数据合并,再通过 cloneWithRows 方法更新 DataSource。如果新数据的长度小于 11,说明还有更多数据,否则已经加载完毕。

在 ListView 的属性中,我们新增了 onEndReached 和 onEndReachedThreshold 两个属性。当用户滚动到距离底部 10 的位置时,就会触发 _loadMore 方法。同时,我们通过 renderFooter 属性来指定底部的渲染方式,根据 hasMore 状态来判断是否需要显示“没有更多了~”的提示。

总结

React Native ListView 组件是 App 开发中常用的组件之一,有多种使用场景。本文对其常见的用法进行了详细的总结和梳理,包括基本用法、横向滚动、下拉刷新、上拉加载等。希望本文能够帮助开发者更好地了解和掌握 ListView 组件,提高工作效率。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a8d9e6add4f0e0ff216004


纠错反馈