天天看点

React Native之SectionList介绍一1.SectionList是什么?2.SectionList支持哪些功能?3.SectionList关键属性?4.使用示例

目录

1.SectionList是什么?

2.SectionList支持哪些功能?

3.SectionList关键属性?

3.1sections

3.2renderItem

3.3非必须属性

3.4方法

4.使用示例

4.1使用示例效果

4.2使用示例详细代码和说明

本组件实质是基于

<VirtualizedList>

组件的封装,继承了其所有 props(也包括所有

<ScrollView>

)的 props)。此外还有下面这些需要注意的事项:

  • 当某行滑出渲染区域之外后,其内部状态将不会保留。请确保你在行组件以外的地方保留了数据。
  • 本组件继承自

    PureComponent

    而非通常的

    Component

    ,这意味着如果其

    props

    浅比较

    中是相等的,则不会重新渲染。所以请先检查你的

    renderItem

    函数所依赖的

    props

    数据(包括

    data

    属性以及可能用到的父组件的state),如果是一个引用类型(Object或者数组都是引用类型),则需要先修改其引用地址(比如先复制到一个新的Object或者数组中),然后再修改其值,否则界面很可能不会刷新。(译注:这一段不了解的朋友建议先学习下js中的基本类型和引用类型。)
  • 为了优化内存占用同时保持滑动的流畅,列表内容会在屏幕外异步绘制。这意味着如果用户滑动的速度超过渲染的速度,则会先看到空白的内容。这是为了优化不得不作出的妥协,而我们也在设法持续改进。
  • 默认情况下每行都需要提供一个不重复的key属性。你也可以提供一个

    keyExtractor

    函数来生成key。

1.SectionList是什么?

通常简单的列表显示会选用FlatList,涉及分组显示列表时(例如:通讯录,城市选择列表)我们会选用SectionList,SectionList主要用于显示分组列表;

城市列表效果图:

React Native之SectionList介绍一1.SectionList是什么?2.SectionList支持哪些功能?3.SectionList关键属性?4.使用示例

2.SectionList支持哪些功能?

a.完全跨平台,即支持IOS和Android。

b.行组件显示或隐藏时可配置回调事件。

c.支持单独的头部组件。

d.支持单独的尾部组件。

e.支持自定义行间分隔线。

f.支持分组的头部组件。

g.支持分组的分隔线。

h.支持多种数据源结构

i.支持下拉刷新。

j.支持上拉加载。

3.SectionList关键属性?

3.1sections

用来渲染的数据,类似于FlatList中的data属性。

sections属性的数据结构,参考:

title:对应可以显示分组的标题;

data:对应显示分组下的内容列表;

{[
    { title: "Title1", data: ["item1", "item2"] },
    { title: "Title2", data: ["item3", "item4"] },
    { title: "Title3", data: ["item5", "item6"] }
  ]}
           

3.2renderItem

用来渲染每一个section中的每一个列表项的默认渲染器。可以在section级别上进行覆盖重写。必须返回一个react组件。

包含三个参数,分别要显示的内容item(object),分组中对应的索引位置index(number),在sections中的完整的对象section(object);

renderItem={({ item, index, section }) => <Text key={index}>{item}</Text>}
           

注意:以上sections和renderItem属性是必须配置的两个属性;

3.3非必须属性

属性名称 属性说明 数据类型 使用示例 备注

keyExtractor

此函数用于为给定的item生成一个不重复的key。Key的作用是使React能够区分同类元素的不同个体,以便在刷新时能够确定其变化的位置,减少重新渲染的开销。若不指定此函数,则默认抽取item.key作为key值。若item.key也不存在,则使用数组下标。注意这只设置了每行(item)的key,对于每个组(section)仍然需要另外设置key。 (item: Item, index: number) => string

keyExtractor={this._keyExtractor}

//定义指定key的函数

_keyExtractor=(item, index) => item.title(返回唯一不重复的key);

initialNumToRender

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

onEndReached

当列表被滚动到距离内容最底部不足

onEndReachedThreshold

的距离时调用。
[(info: {distanceFromEnd: number}) => void]
onEndReached={()=>this.onEndReached()}
onEndReachedThreshold = { 0.5 }
           
//达到设置距离要求则回调该方法
onEndReached() {
    console.log("onEndReached");
    if(!this.isLastPage){
        this.page = this.page+1;
        this.loadData(false);
    }
}
           
onEndReachedThreshold 决定当距离内容最底部还有多远时触发

onEndReached

回调。注意此参数是一个比值而非像素单位。比如,0.5表示距离内容最底部的距离为当前列表可见长度的一半时触发。
number onEndReachedThreshold = { 0.5 }

extraData

如果有除

data

以外的数据用在列表中(不论是用在

renderItem

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

ItemSeparatorComponent

行与行之间的分隔线组件。不会出现在第一行之前和最后一行之后。 [component, function, element]
ItemSeparatorComponent={this._showDivideLine.bind(this)}
           
//返回分割线组件
_showDivideLine =() =>{
    return <View style={styles.divideLine} />;
}
           

inverted

翻转滚动方向。实质是将scale变换设置为-1。 boolean [component, function, element]

ListFooterComponent

尾部组件。

ItemSeparatorComponent使用类似

ListEmptyComponent

当列表数据为空时渲染的组件。 [component, function, element] 显示内容为空时显示该组件,

使用

组件参考

ItemSeparatorComponent类似

onRefresh

如果设置了此选项,则会在列表头部添加一个标准的

RefreshControl

控件,以便实现“下拉刷新”的功能。同时你需要正确设置

refreshing

属性。如果你想把刷新控件往下移动一些(比如100个pt),可以设置

progressViewOffset={100}

[() => void]
refreshControl={
    <RefreshControl
        refreshing={false}
        onRefresh={this.reloadWordData.bind(this)}
    />}
           
 //刷新方法回调
reloadWordData() {}
           

refreshing

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

ListHeaderComponent

头部组件。 component, function, element 显示头部组件,

使用

组件参考

ItemSeparatorComponent类似

renderSectionHeader

在每个section的头部渲染。在iOS上,这些headers是默认粘接在

ScrollView

的顶部的. 参见[

stickySectionHeadersEnabled

]。
[(info: {section: SectionT}) => ?React.Element]
renderSectionHeader={({section}) =>this._sectionComp(section)}
           
_sectionComp(section){//textAlign: 'center',
    let txt = section.keyvalue;
    return <Text
        style={{ height: 50, backgroundColor: '#9CEBBC', color: 'white', textAlignVertical: 'center',fontSize: 30
            ,width: Dimensions.get("window").width}}>{txt}</Text>
}
           

renderSectionFooter

每个组的尾部组件。 [(info: {section: SectionT}) => ?React.Element]

SectionSeparatorComponent

在每个

section

的顶部和底部渲染(区别于

ItemSeparatorComponent

,它仅在列表项之间渲染)。它的作用是为了从视觉上把

section

与它上方或下方的

headers

区别开来,从这个意义上讲,它的作用和

ItemSeparatorComponent

是一样的. 它也接受

highlighted

[leading/trailing][Item/Separator]

这两个默认提供的属性或其他通过

separators.updateProps

添加的自定义属性.
SectionSeparatorComponent={this._showSectionDivideLine.bind(this)}
           
_showSectionDivideLine =() =>{
    return <View style={styles.sectiondivideLine} />;
}
           

stickySectionHeadersEnabled

当下一个section把它的前一个section的可视区推离屏幕的时候,让这个section的header粘连在屏幕的顶端。这个属性在iOS上是默认可用的,因为这是iOS的平台规范。 boolean

3.4方法

方法名 方法说明 参数说明 备注
scrollToLocation(params); 将可视区内位于特定

sectionIndex

 或 

itemIndex

 (section内)位置的列表项,滚动到可视区的制定位置。比如说,

viewPosition

 为0时将这个列表项滚动到可视区顶部 (可能会被顶部粘接的header覆盖), 为1时将它滚动到可视区底部, 为0.5时将它滚动到可视区中央。

(注意: 如果没有设置

getItemLayout

或是

onScrollToIndexFailed

,就不能滚动到位于外部渲染区的位置。)

params:类型object

Valid 

params

 keys are:
  • 'animated' (boolean) - Whether the list should do an animation while scrolling. Defaults to 

    true

    .
  • 'itemIndex' (number) - Index within section for the item to scroll to. Required.
  • 'sectionIndex' (number) - Index for section that contains the item to scroll to. Required.
  • 'viewOffset' (number) - 一个以像素为单位,到最终位置偏移距离的固定值,比如为了弥补粘接的header所占据的空间。
  • 'viewPosition' (number) - A value of   places the item specified by index at the top, 

    1

     at the bottom, and 

    0.5

     centered in the middle.
使用示例说明:
 this.sectionList.scrollToLocation(
            {
                sectionIndex: k,//右边字母点击后的索引值 k
                itemIndex: 0,
                viewOffset: HEADER_HEIGHT,//向下偏移一个头部高度
            }
        );
           

recordInteraction()

主动通知列表发生了一个事件,以使列表重新计算可视区域。比如说当

waitForInteractions

 为 true 并且用户没有滚动列表时,就可以调用这个方法。不过一般来说,当用户点击了一个列表项,或发生了一个导航动作时,我们就可以调用这个方法。
flashScrollIndicators 短暂地显示滚动指示器。

4.使用示例

4.1使用示例效果

React Native之SectionList介绍一1.SectionList是什么?2.SectionList支持哪些功能?3.SectionList关键属性?4.使用示例

4.2使用示例详细代码和说明

import React, {Component} from 'react'
import {
    View,
    Text,
    SectionList,
    Dimensions,
    StyleSheet,
    TouchableOpacity
} from 'react-native';

export default class TabThree extends Component{
    constructor(props){
        super(props);
        this.sectionData =
            [
                {
                    "keyvalue":"A",
                    "data":[
                        {
                            "name":"阿诗玛",
                            "desc":"ASM",
                        },
                        {
                            "name":"阿沙克",
                            "desc":"ASM",
                        }
                    ]
                },
                {
                    "keyvalue":"B",
                    "data":[
                        {
                            "name":"棒槌山",
                            "desc":"ASM",
                        },
                        {
                            "name":"半岛山",
                            "desc":"ASM",
                        }
                    ]
                },
                {
                    "keyvalue":"C",
                    "data":[
                        {
                            "name":"曹仓",
                            "desc":"ASM",
                        },
                        {
                            "name":"曹植",
                            "desc":"ASM",
                        }
                    ]
                },
                {
                    "keyvalue":"D",
                    "data":[
                        {
                            "name":"邓超",
                            "desc":"ASM",
                        },
                        {
                            "name":"邓毅",
                            "desc":"ASM",
                        }
                    ]
                }
            ];
    }

    render(){
        return (<View style={styles.container}>
                    <SectionList
                        // style={{height:300}}
                        sections={this.sectionData}    //配置数据源
                        renderSectionHeader={({section})     =>this._sectionComp(section)}    //分组标题
                        renderItem={({item, index, section}) => this._renderItem(item, index, section)}    //分组下单条内容
                        keyExtractor={this._keyExtractor}    //设置唯一key
                        initialNumToRender={10}    //初始化渲染显示内容条数
                        onEndReached={()=>this.onEndReached()}    //监听距离底部距离回调
                        onEndReachedThreshold = { 0.5 } //监听距离底部距离回
                        ItemSeparatorComponent={this._showDivideLine.bind(this)}//分割线组件
                        SectionSeparatorComponent={this._showSectionDivideLine.bind(this)}    //Section分割线组件
                        stickySectionHeadersEnabled={true}    //section标题可以浮动
                        />
                </View>);
    }

    _showDivideLine =() =>{
        return <View style={styles.divideLine} />;
    }

    _showSectionDivideLine =() =>{
        return <View style={styles.sectiondivideLine} />;
    }

    onEndReached() {
        console.log("onEndReached");

    }

    //定义指定key的函数
    _keyExtractor=(item, index) => item.keyvalue;

    _sectionComp(section){//textAlign: 'center',
        let txt = section.keyvalue;
        return <Text
            style={{ height: 50, backgroundColor: '#9CEBBC', color: 'white', textAlignVertical: 'center',fontSize: 30
                ,width: Dimensions.get("window").width}}>{txt}</Text>
    }

    _renderItem =(item, index, section) =>{
        let txt = item.name;
        return (<TouchableOpacity style={{ height: 60, width: Dimensions.get("window")/3, backgroundColor: "#ffffff"}}
                                  activeOpacity={0.5} >
            <Text style={{height: 60, textAlignVertical: 'center', color: '#5C5C5C', fontSize: 15 }}>{txt}</Text>
        </TouchableOpacity>);
    }



}

var styles = StyleSheet.create({
    container:{
        flex: 1,
        justifyContent: 'center',
        alignItems:'center',
    },
    divideLine:{
        height: 1,
        width:'100%',
        backgroundColor: '#0000ff',
    },
    sectiondivideLine:{
        height: 5,
        width:'100%',
        backgroundColor: '#ff00ff',
    },
});
           

参考:

https://reactnative.cn/docs/sectionlist/#itemseparatorcomponent

继续阅读