zoukankan      html  css  js  c++  java
  • 史上最易懂——ReactNative分组列表SectionList使用详情及示例详解

     React Native系列

    《逻辑性最强的React Native环境搭建与调试》 

    《ReactNative开发工具有这一篇足矣》 

    《解决React Native unable to load script from assets index.android.bundle on windows》 

    《React Native App设置&Android版发布》

    《史上最易懂——ReactNative分组列表SectionList使用详情及示例详解》


    目录

    1、SectionList简述
    2、SectionList常用属性和方法
    3、SectionList示例,通讯录实现以及源码

    正文

    1、SectionList简述

    ReactNative长列表数据组件一共有三个:
      ListView 核心组件,数据量大时性能较差,占用内存持续增加,故设计出来FlatList组件。
      FlatList 用于替代ListView,支持下拉刷新和上拉加载。
      SectionList 高性能的分组列表组件。
    本文重点介绍SectionList,SectionList支持下面的常用功能:
      完全跨平台
      支持水平布局模式
      行组件显示或隐藏时可配置回调事件
      支持单独的头部组件
      支持单独的尾部组件
      支持自定义行间分隔线
      支持下拉刷新
      支持上拉加载

    2、SectionList常用属性和方法

    属性集合

    属性名

    类型

    说明

    sections

    Array

    数据源

    ItemSeparatorComponent

    ReactClass<any>

    行与行之间的分隔线组件。不会出现在第一行之前和最后一行之后

    SectionSeparatorComponent 

    ReactClass<any>

    每个section之间的分隔组件

    ListEmptyComponent ReactClass<any> | React.Element<any>

    列表为空时渲染该组件。可以是React Component, 也可以是一个render函数, 或者渲染好的element。

    ListFooterComponent

    ReactClass<any>

    尾部组件

    ListHeaderComponent

    ReactClass<any>

    头部组件

    data

    Array<ItemT>

    为了简化起见,data属性目前只支持普通数组。如果需要使用其他特殊数据结构,例如immutable数组,请直接使用更底层的VirtualizedList组件

    extraData

    any

    如果有除data以外的数据用在列表中(不论是用在renderItem还是Header或者Footer中),请在此属性中指定。同时此数据在修改时也需要先修改其引用地址(比如先复制到一个新的Object或者数组中),然后再修改其值,否则界面很可能不会刷新。

    getItem

    any

    获取控件的绑定数据

    getItemCount

    any

    获取绑定数据的条数

    getItemLayout

    (data: ?Array<ItemT>, index: number) => {length: number, offset: number, index: number}

    getItemLayout是一个可选的优化,用于避免动态测量内容尺寸的开销,不过前提是你可以提前知道内容的高度。如果你的行高是固定的,getItemLayout用起来就既高效又简单,类似下面这样:

    getItemLayout={(data, index={length: 行高, offset: 行高 * index, index)}

    注意如果你指定了SeparatorComponent,请把分隔线的尺寸也考虑到offset的计算之中。

    initialNumToRender

    number 

    指定一开始渲染的元素数量,最好刚刚够填满一个屏幕,这样保证了用最短的时间给用户呈现可见的内容。注意这第一批次渲染的元素不会在滑动过程中被卸载,这样是为了保证用户执行返回顶部的操作时,不需要重新渲染首批元素。

    keyExtractor

    (item: ItemT, index: number) => string

    此函数用于为给定的item生成一个不重复的key。Key的作用是使React能够区分同类元素的不同个体,以便在刷新时能够确定其变化的位置,减少重新渲染的开销。若不指定此函数,则默认抽取item.key作为key值。若item.key也不存在,则使用数组下标。

    legacyImplementation

    boolean 

    设置为true则使用旧的ListView的实现

    onEndReached

    (info: {distanceFromEnd: number}) => void

    当列表被滚动到距离内容最底部不足onEndReachedThreshold的距离时调用

    onEndReachedThreshold

    number 

    决定当距离内容最底部还有多远时触发onEndReached回调。注意此参数是一个比值而非像素单位。比如,0.5表示距离内容最底部的距离为当前列表可见长度的一半时触发

    onRefresh

    void

    如果设置了此选项,则会在列表头部添加一个标准的RefreshControl控件,以便实现“下拉刷新”的功能。同时你需要正确设置refreshing属性

    onViewableItemsChanged

    (info: {viewableItems: Array<ViewToken>, changed: Array<ViewToken>}) => void

    在可见行元素变化时调用。可见范围和变化频率等参数的配置请设置viewabilityconfig属性

    refreshing

    boolean 

    在等待加载新数据时将此属性设为true,列表就会显示出一个正在加载的符号

    renderItem

    (info: {item: ItemT, index: number}) => ?React.Element<any>

    根据行数据data渲染每一行的组件

    viewabilityConfig

    ViewabilityConfig 

    请参考ViewabilityHelper的源码来了解具体的配置

    方法集合:

    方法名 说明

    scrollToLocation

    将可视区内位于特定sectionIndex 或 itemIndex (section内)位置的列表项,滚动到可视区的制定位置。比如说,viewPosition 为0时将这个列表项滚动到可视区顶部 (可能会被顶部粘接的header覆盖), 为1时将它滚动到可视区底部, 为0.5时将它滚动到可视区中央。viewOffset是一个以像素为单位,到最终位置偏移距离的固定值,比如为了弥补粘接的header所占据的空间

    注意: 如果没有设置getItemLayout,就不能滚动到位于外部渲染区的位置。

    recordInteraction

    主动通知列表发生了一个事件,以使列表重新计算可视区域。比如说当waitForInteractions 为 true 并且用户没有滚动列表时,就可以调用这个方法。不过一般来说,当用户点击了一个列表项,或发生了一个导航动作时,我们就可以调用这个方法。

    flashScrollIndicators

    短暂地显示滚动指示器。

    3、SectionList示例,通讯录实现以及源码

    源码:

    import React, { Component } from 'react';
    import {
      AppRegistry,
      View,
      Text,
      SectionList,
    } from 'react-native';
    
    
    
    class HomeScreen extends React.Component {
    
      constructor(props) {
        super(props);
      }
    
      _renderItem = (info) => {
        var txt = '  ' + info.item.title;
        return <Text
          style={{ height: 60, textAlignVertical: 'center', backgroundColor: "#ffffff", color: '#5C5C5C', fontSize: 15 }}>{txt}</Text>
      }
    
      _sectionComp = (info) => {
        var txt = info.section.key;
        return <Text
          style={{ height: 50, textAlign: 'center', textAlignVertical: 'center', backgroundColor: '#9CEBBC', color: 'white', fontSize: 30 }}>{txt}</Text>
      }
    
      render() {
        var sections = [
          { key: "A", data: [{ title: "阿童木" }, { title: "阿玛尼" }, { title: "爱多多" }] },
          { key: "B", data: [{ title: "表哥" }, { title: "贝贝" }, { title: "表弟" }, { title: "表姐" }, { title: "表叔" }] },
          { key: "C", data: [{ title: "成吉思汗" }, { title: "超市快递" }] },
          { key: "W", data: [{ title: "王磊" }, { title: "王者荣耀" }, { title: "往事不能回味" },{ title: "王小磊" }, { title: "王中磊" }, { title: "王大磊" }] },
        ];
    
        return (
          <View style={{ flex: 1 }}>
            <SectionList
              renderSectionHeader={this._sectionComp}
              renderItem={this._renderItem}
              sections={sections}
              ItemSeparatorComponent={() => <View><Text></Text></View>}
              ListHeaderComponent={() => <View style={{ backgroundColor: '#25B960', alignItems: 'center', height: 30 }}><Text style={{ fontSize: 18, color: '#ffffff' }}>通讯录</Text></View>}
              ListFooterComponent={() => <View style={{ backgroundColor: '#25B960', alignItems: 'center', height: 30 }}><Text style={{ fontSize: 18, color: '#ffffff' }}>通讯录尾部</Text></View>}
            />
          </View>
        );
      }
    
    }
    
    AppRegistry.registerComponent('App', () => HomeScreen);
    

    附源码github地址:https://github.com/vipstone/react-nation-sectionlist

    小技巧:如何隐藏header?

    static navigationOptions = {
      header: null
    };

    设置header为null即可隐藏。

  • 相关阅读:
    memcache详解
    redis详解
    laravel5表单验证
    MySQL添加字段和修改字段
    delete和truncate区别
    IOC 和DI(转载)
    JPA和SpringData知识梳理
    spring和springmvc配置分离
    springboot 整合 mybatis
    mongodb安装及配置
  • 原文地址:https://www.cnblogs.com/vipstone/p/7250625.html
Copyright © 2011-2022 走看看