天天看點

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

繼續閱讀