iOS猿媛圈Swift DeveloperiOS开发记录

ReactNative-可折叠列表(SectionList)

2019-01-11  本文已影响0人  FlyElephant

iOS中实现可折叠的列表通过UITableView实现非常简单,ReactNative可以通过UITableView的替代者SectionList来实现,实现代码如下:

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

var originalData = [
    {data: ['积分是公司虚拟货币,用户可以通过完成指定任务或参与活动等方式获得积分,积分可用于获取福利,如兑换商品和抽奖等。']},
    {data: [{row1: {title: '1、投资即可获得积分,投资金额越高,期限越长,获得积分越多,详情如下:',
                    line1: '投资理财计划:所得积分=投资本金*0.05',
                    line2: '积分获取按实际投资金额计算'},
             row2: {
                 title: '2、通过参加任务或活动获得积分,具体以任务或活动规则为准。',
             }
    }]},
    {data: ['可在积分商城兑换商品,也可用于参与活动,更多详情可进入积分中心首页查看']},
    {data: [{title: '完成投资,积分即刻派发至个人积分账户。',
        content : '选择续期,积分将在续期完成后,即刻派发至个人积分账户'}]},
    {data: [{title: '每个积分有效期为一年', line1: '用户通过任何作弊行为获取积分,一经发现扣除该用户全部积分',
        line2: '积分所有内容解释权归公司所有'}]}
];

class CircleRow extends Component {
    render() {
        return (
            <View style = {{flexDirection:'row',marginLeft: 15, marginRight: 15, marginBottom: 15}}>
                <View style = {[styles.circle]}></View>
                <Text style={[{lineHeight: 20,marginLeft: 10, marginTop: -5, fontSize: 13},this.props.style]}>{this.props.name}</Text>
            </View>
        );
    }
}

export default class MySectionList extends Component {

    constructor(props) {
        super(props);
        this.state = {
            displayData: [
                {title: '什么是积分'},
                {title: '积分如何获得'},
                {title: '积分如何使用'},
                {title: '积分派发时间'},
                {title: '积分有效期'}
            ]
        };

        for (var i = 0; i < this.state.displayData.length; i++) {
            this.state.displayData[i]['data'] = [];
            this.state.displayData[i]['key'] = i;
            this.state.displayData[i]['isExpanded'] = '0';
        }
    }

    _sectionHeader = (data) => {
        console.log('========'+JSON.stringify(data));
        var imgPath = data.section.isExpanded == '0' ?  require('./down.png') : require('./up.png');
         return <TouchableOpacity style = {styles.sectionHeader} fontSize = {15}   color = {'#333333'}
                              onPress={()=>{ this.toggle(data); }}>
                <View style = { styles.sectionContainer }>
                    <Text style = { styles.sectionText } numberOfLines = { 1 } >{data.section.title}</Text>
                    <View style = { styles.sectionImage }>
                        <Image source = { imgPath } style = { {width: 12, height: 12} }/>
                    </View>
                </View>
            </TouchableOpacity>
    };

    _sectionItem = (data) => {
        console.log('当前的item:'+JSON.stringify(data));
        if(data.section.key == 0) {
            return <Text style={[styles.item, {lineHeight: 20}]} fontSize = {20} >{data.item}</Text>
        } else if(data.section.key == 1) {
            return <View>
                <Text style={[styles.item, {lineHeight: 20}]}>{data.item.row1.title}</Text>
                <View style = {{marginLeft: 15, marginRight: 15, marginBottom: 20}}>
                    <View style = { styles.tableHeader }>
                        <Text style = { [styles.tableHeaderText, styles.tableBorder, {flex: 10}] }>投资产品类别</Text>
                        <Text style = { [styles.tableHeaderText, styles.tableBorder, {flex: 15}] }>获得积分</Text>
                    </View>
                    <View style = {{flex: 1, flexDirection: 'row', height: 120, backgroundColor: '#F7F9FC'}}>
                        <View style = {[{flex: 10, alignItems: 'center', justifyContent: 'center'},styles.tableBorder]}>
                            <Text style = {{fontSize: 12}}>计划1</Text>
                            <Text style = {{fontSize: 12, marginTop: 5}}>计划2</Text>
                            <Text style = {{fontSize: 12, marginTop: 5}}>计划3</Text>
                        </View>
                        <View style = {[{flex: 15, paddingTop: 10},styles.tableBorder]}>
                            <Text style = {{fontSize: 12, marginLeft: 10, marginRight: 10}}>投资金额*锁定期/12*0.05</Text>
                            <Text style = {{fontSize: 12, marginLeft: 10, marginRight: 10, marginTop: 8, color: '#3F3F3F', lineHeight: 15}}>举例:投资1万元,可获得250积分</Text>
                            <Text style = {{fontSize: 12, marginLeft: 10, marginRight: 10, marginTop: 8, color: '#3F3F3F', lineHeight: 20}}>计划锁定期为1个月,12月期以上产品锁定期均按12个月计算</Text>
                        </View>
                    </View>
                    <View style = {[styles.tableHeader, {height: 130}]}>
                        <Text style = { [styles.tableHeaderText, styles.tableBorder, {flex: 10, lineHeight: 130, fontSize: 12}] }>计划4</Text>
                        <View style = {[{flex: 15, height: 130, paddingTop: 15}, styles.tableBorder]}>
                            <Text style = {{fontSize: 12, marginLeft: 10, marginRight: 10, lineHeight: 20}}>每笔投资金额*(到期时间-每次投资时间)/12*0.05</Text>
                            <Text style = {{fontSize: 12, marginLeft: 10, marginRight: 10, marginTop: 5, color: '#3F3F3F', lineHeight: 20}}>举例:首次投资1000元,获得50积分以此类推</Text>
                        </View>
                    </View>
                    <View style = { [styles.tableHeader, {backgroundColor: '#F7F9FC'}]}>
                        <Text style = { [styles.tableHeaderText, styles.tableBorder, {flex: 10, fontSize: 12}] }>计划5</Text>
                        <Text style = { [styles.tableHeaderText, styles.tableBorder, {flex: 15, color: '#999999', fontSize: 12}] }>不参与积分获取</Text>
                    </View>
                </View>
                <CircleRow name = {data.item.row1.line1}/>
                <CircleRow name = {data.item.row1.line2} style={{marginTop: -8}}/>
                <Text style={[styles.item, {lineHeight: 20}]}>{data.item.row2.title}</Text>
            </View>
        } else if(data.section.key == 2) {
            return <Text style={[styles.item, {lineHeight: 20}]}>{data.item}</Text>
        } else if(data.section.key == 3) {
            return <View>
                     <Text style={[styles.item, {lineHeight: 20}]}>{data.item.title}</Text>
                     <CircleRow name = {data.item.content}/>
                   </View>
        } else if(data.section.key == 4){
            return <View>
                <Text style={[styles.item, {lineHeight: 20}]}>{data.item.title}</Text>
                <CircleRow name = {data.item.line1}/>
                <CircleRow name = {data.item.line2} style={{marginTop: -8}}/>
            </View>
        } else {
            return <Text style={[styles.item, {lineHeight: 20}]}>{data.item}</Text>
        }
    };

    toggle(data) {
        var key = data.section.key;
        if (data.section.isExpanded == '0') {
            this.state.displayData[key].data = originalData[key].data;
            this.state.displayData[key].isExpanded = '1';
        } else {
            this.state.displayData[key].data = [];
            this.state.displayData[key].isExpanded = '0';
        }
        this.setState({
            displayData: this.state.displayData
        });
    }

    extraUniqueKey(item, index) {
        return index + item;
    }

    render() {
        return (
            <View style={styles.container}>
                <SectionList
                    sections = { this.state.displayData }
                    renderItem = { this._sectionItem.bind(this) }
                    renderSectionHeader = { this._sectionHeader.bind(this) }
                    keyExtractor = { this.extraUniqueKey }//去除警告
                />
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        paddingTop: 22
    },
    sectionHeader: {
        height: 60,
        backgroundColor: 'gray',
        justifyContent: 'center'
    },
    sectionContainer: {
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center'
    },
    sectionText: {
        flex: 22,
        paddingLeft: 15,
        backgroundColor: 'red'
    },
    sectionImage: {
        flex: 3,
        justifyContent: 'center',
        alignItems: 'center'
    },
    item: {
        paddingLeft: 15,
        paddingRight: 15,
        marginTop: 15,
        marginBottom: 15,
        fontSize: 13
    },
    circle: {
        width: 8,
        height: 8,
        backgroundColor:'#f76260',
        borderRadius: 4
    },
    tableHeader: {
        flex: 1,
        flexDirection: 'row',
        height: 45,
        backgroundColor: '#EFF3F9',
        alignItems: 'center'
    },
    tableHeaderText: {
        fontSize: 13,
        textAlign: 'center',
        lineHeight: 45
    },
    tableBorder: {
        borderWidth: 0.5,
        borderColor: '#E0E8F2'
    }
});
上一篇 下一篇

猜你喜欢

热点阅读