zoukankan      html  css  js  c++  java
  • reactnative SectionList使用

    SectionList可以用于展示有多个分区的列表。

    SectionList常用属性和方法 

    sections: Array相当于ListView中的数据源,SectionList所需要的数据都是经由sections属性传入,数据类型为Array类型

    renderItem: (info: {item: Item, index: number}) => ?React.Element renderItem返回Section中的每个小的的Item。可以通过函数返回Element,函数有一个info参数,参数为JSON形式,参数形式为:{item: Item, index: number}。

    renderSectionHeader: (info: {section: SectionT}) => ?React.Element renderSectionHeader返回每个Section的标志性头部,可以通过函数返回Element,函数有一个info参数,参数为JSON形式,参数形式为:{section:{key : number, data : [ Object, Object, …] }}。

    refreshing: boolean 是否处于刷新状态。

    onRefresh: () => void 通过函数改变refreshing从而控制刷新与否。

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

    SectionSeparatorComponent : ReactClass .每个section之间的分隔组件。

    ListHeaderComponent : ReactClass SectionList头部组件。

    ListFooterComponent : ReactClass SectionList尾部组件。

    keyExtractor: (item: Item, index: number) => string 默认情况下每个item都需要提供一个不重复的key属性,因此可以通过keyExtractor函数为每一个item生成一个唯一的key。

    onEndReached : (info: {distanceFromEnd: number}) => void 是否到达底部,在默认情况下会有一个默认的distanceFromEnd临界值。可以通过此属性来达到上拉加载的效果。

    onEndReachedThreshold number 调用onEndReached之前的临界值,单位是像素

     

    注意点:

    还有一个使用这个组件比较坑的地方是它只接受,key,data这样的数据类型,所以如果后台返回给的数据不是这样的格式的话需要转换一下在使用。

    /**
    * 将数据转化为sectionList需要的数据格式
    * @param data
    * @returns {Array}
    */
    changeGoodsData(data){
    let jsonData = data
    //每组的开头在列表中的位置
    let totalSize = 0;
    //SectionList的数据源
    let cityInfos = [];
    //分组头的数据源
    let citySection = [];
    //分组头在列表中的位置
    let citySectionSize = [];
    for (let i = 0; i < jsonData.length; i++) {
    citySectionSize[i] = totalSize;
    //给右侧的滚动条进行使用的
    citySection[i] = jsonData[i].catName;
    let section = {}
    section.key = jsonData[i].catName;
    section.data = jsonData[i].goods;
    for (let j = 0; j < section.data.length; j++) {
    section.data[j].key = j
    }
    cityInfos[i] = section;
    //每一项的header的index
    totalSize += section.data.length + 1
    }
    return cityInfos;

    }


    实例

    import React, {PureComponent} from 'react';
    import {FlatList, TouchableOpacity, Text, View, TextInput, StyleSheet, Image, Alert,SectionList} from 'react-native';
    import {Actions, ActionConst} from 'react-native-router-flux';
    import Button from "apsl-react-native-button"//自定义button
    import {color, tv_size} from "../../common/Constants";
    import src from "../../common/Image";

    export default class TodayLeadingAddPage extends PureComponent {
    dataContainer = [];

    constructor(props) {
    super(props);
    this.state = {
    /**假设1为选择,2为取消*/
    sourceData: [
    { key: "招牌菜-3", data: [{ title: "鱼香茄子",type:1 }, { title: "酸菜鱼",type:2 }, { title: "红烧肉",type:1 }] },
    { key: "凉菜-12", data: [{ title: "花生米" ,type:2}, { title: "黄瓜",type:1 }] },
    { key: "主食-8", data: [{ title: "米饭" ,type:1},] },
    ]
    , selected: (new Map(): Map<String, boolean>)
    , refreshing: false
    , indexText: ''
    }
    }

    componentDidMount() {

    }

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

    /**
    * 使用箭头函数防止不必要的re-render;
    * 如果使用bind方式来绑定onPressItem,每次都会生成一个新的函数,导致props在===比较时返回false,
    * 从而触发自身的一次不必要的重新render,也就是FlatListItem组件每次都会重新渲染。
    *
    * @param id
    * @private
    */
    _onPressItem = (id: string) => {
    this.setState((state) => {
    const selected = new Map(state.selected);
    selected.set(id, !selected.get(id));
    return {selected}
    });

    //CustomToastAndroid.show(JSON.stringify(id), CustomToastAndroid.SHORT);
    };




    // 下拉刷新
    _renderRefresh = () => {
    this.setState({refreshing: true})//开始刷新
    //这里模拟请求网络,拿到数据,3s后停止刷新
    setTimeout(() => {
    //CustomToastAndroid.show('没有可刷新的内容!', CustomToastAndroid.SHORT);
    this.setState({refreshing: false});
    }, 1000);
    };

    // 上拉加载更多
    _onEndReached = () => {

    };
    /**点击选择或者取消*/
    clickItem(item){
    if(item.type===1){
    alert('选择');
    }else
    {
    alert('取消');
    }
    }


    /**单元格*/
    _renderItem = ({item}) => {
    return (
    <FlatListItem
    id={item.id}
    type={item.type}
    onClick={()=>this.clickItem(item)}
    onPressItem={this._onPressItem}
    selected={!!this.state.selected.get(item.id)}
    title={item.title}
    />
    );
    };




    /**区头*/
    _sectionComp = (info) => {
    var txt = info.section.key;
    return (<View style={{height: 50, backgroundColor: 'white'}}>
    <View style={{height:10,backgroundColor:'#eee'}}>
    </View>
    <View style={{height: 40, backgroundColor: 'white',justifyContent:'center'}}>
    <Text
    style={{color: color.color_grey_3, fontSize:tv_size.dp30,marginLeft:10}}>
    {txt}
    </Text>
    </View>

    <Image source={src.line} style={{ null, height: 1}} resizeMode='stretch'/>
    </View>);
    }


    render() {
    return (
    <View style={{flex:1}}>

    <SectionList
    ref={ref => this.SectionList = ref}
    renderSectionHeader={this._sectionComp}
    renderItem={this._renderItem}
    sections={this.state.sourceData}
    extraData={this.state.selected}
    keyExtractor={this._keyExtractor}
    onEndReachedThreshold={0.1}
    // 当列表被滚动到距离内容最底部不足onEndReacchedThreshold设置的距离时调用
    onEndReached={this._onEndReached}
    refreshing={this.state.refreshing}
    onRefresh={this._renderRefresh}
    />

    </View>

    );
    }
    }

    class FlatListItem extends React.PureComponent {
    _onPress = () => {
    this.props.onPressItem(this.props.id);
    };

    render() {
    return (
    <TouchableOpacity
    {...this.props}
    onPress={this._onPress}
    >
    <View style={{
    backgroundColor: '#eee',
    }}>
    <View style={styles.item_container}>
    <View style={{flexDirection: 'row', alignItems: 'center'}}>
    <Image style={{marginLeft:10,height:64,64,backgroundColor:'red',borderRadius:5}}/>
    <View style={{margin: 15}}>
    <Text style={{color: color.color_grey_3, fontSize: tv_size.dp32}}>{this.props.title}</Text>
    <View style={{flexDirection: 'row', marginTop: 10}}>
    <Text style={{color: color.color_grey_6, fontSize: tv_size.dp24}}>现价:</Text>
    <Text style={{color: color.color_org_red, fontSize: tv_size.dp24}}>¥28</Text>
    </View>
    <View style={{flexDirection: 'row', marginTop: 10,}}>
    <Text style={{color: color.color_grey_6, fontSize: tv_size.dp24,textDecorationLine:'line-through'}}>原价:¥28</Text>
    </View>

    </View>
    </View>

    <View style={{alignSelf:'flex-end',marginBottom:10,marginRight: 10}}>
    <TouchableOpacity onPress={this.props.onClick}>
    <Image source={this.props.type===1? src.ic_goods_select:src.ic_goods_cancel} />
    </TouchableOpacity>
    </View>


    </View>
    <Image source={src.line} style={{ null, height: 1}} resizeMode='stretch'/>
    </View>
    </TouchableOpacity>
    );
    }
    }
    var styles = StyleSheet.create({
    base_view: {flex: 1, backgroundColor: '#eee'},
    text_item: {
    padding: 10, flex: 1, backgroundColor: '#fff', borderWidth: 1,
    borderColor: '#0f80ff', marginLeft: 10
    },
    item_container: {
    backgroundColor: 'white',
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between'
    }
    });
  • 相关阅读:
    xe5 android tts(Text To Speech) [转]
    xe5 android sample 中的 SimpleList 是怎样绑定的 [转]
    xe5 android 控制蓝牙[转]
    xe5 android 调用照相机获取拍的照片[转]
    XE5 Android 开发数据访问手机端[转]
    XE5 Android 开发实现手机打电话和发短信 [转]
    让VCL的皮肤用在手机程序里 让安桌程序不山寨[转]
    XE5 Android 开发数据访问server端[转]
    XE5 Android 开发实现手机打电话和发短信[转]
    Delphi XE5的Android开发平台搭建[转]
  • 原文地址:https://www.cnblogs.com/cui-cui/p/9015508.html
Copyright © 2011-2022 走看看