react native 做用户列表

需求:
从API上请求下来的用户数据,做成一个类似通讯录的模式

请求下来的数据格式:
在这里插入图片描述

//获取数据的方法
CustomerList().then(res => {
            let data = res.data
            var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ#".split("");
            var segs = []; // 存放数据
            var res = {};
            let curr;
            var re = /[^\u4e00-\u9fa5]/;//中文正则
            letters.filter((items, i) => {
                curr = {
                    title: '', //字母
                    data: [],  //数据
                };
                data.map((v, index) => {
                //将首字母相同的放到一起,如果涉及到用户名是中文的,可以先解析成英文,可以自行查一下
                    if (v.name[0].toUpperCase() == items) {
                        curr.data.push(v);
                    }
                    //将首字母是中文的以及数字的放到#下
                    if (!re.test(v.name[0]) || !isNaN(v.name[0])) {
                        if (items === "#") {
                            curr.data.push(v);
                        }
                    }
                   //将数据集中到一块
                    if (curr.data.length) {
                        curr.title = letters[i]
                        segs.push(curr);
                    }
                })
                res.segs = Array.from(new Set(segs)) //去重
                return res
            })

           //console.log(res.segs)
           //传入数据计算高度,下文有方法
           this._setItemLayout(res.segs);

        })

整理后数据格式
在这里插入图片描述
现在数据格式很符合需求了,那么就开始套数据

我们使用SectionList来做这件事

<SectionList
     //这里是做点击右侧字母定位用的
    ref={(ref) => { this.sectionList = ref }}
    showsVerticalScrollIndicator={false}
    //getItemLayout很关键,下面说
    getItemLayout={this._getItemLayout.bind(this)}
    keyExtractor={this._keyExtractor}
    //这里的data就是上面返回的data
    sections={data}
    renderItem={({ item }) => {
    //以下是页面的展示代码
        return (
            <View style={styles.sectionItem}>
                <TouchableOpacity onPress={() => {
                    //这里做页面跳转
                }}>
                    <View style={{ flexDirection: "row", width: width - 90 }}>
                        <View style={{ width: 46, height: 46, borderRadius: 25, backgroundColor: "#C7D7E4", justifyContent: "center", alignItems: "center" }}>
                            <Text style={{ fontSize: 16, color: "#fff", fontWeight: "700" }}>{item.name[0].toUpperCase()}</Text>
                        </View>
                        <View style={{ marginLeft: 15 }}>
                            <Text style={{ fontSize: 14, color: "#393939", fontWeight: "700", marginBottom: 5 }}>{item.name}</Text>
                            <Text style={{ fontSize: 12, color: "#828282", marginBottom: 5 }}>{item.phone}</Text>
                            <Text style={{ fontSize: 12, color: "#828282", marginBottom: 5 }}>{item.email}</Text>
                        </View>
                    </View>
                </TouchableOpacity>
            </View>
        )
    }}
    //这里是每组数据的title,即A,B,C这些
    renderSectionHeader={({ section }) => <View style={styles.sectionHeader}><Text style={styles.sectionHeaderTxt}>{section.title}</Text></View>}
/>

这里是右侧字母的列表

<View style={styles.sectionTitleList}>
    {
        list.map((v, k) => {
            return (
                <Text style={styles.titleText} key={k} onPress={() => { this._onSectionselect(k) }}>{v.title}</Text>
            )
        })
    }
</View>

在获取到API数据并且转换之后要对每一条数据的高度进行计算,为点击字母页面滚动到对应位置滚动做准备

 //计算每个index的length和offset
    _setItemLayout(list) {
        let [itemHeight, headerHeight] = [ITEM_HEIGHT, HEADER_HEIGHT];
        let layoutList = [];
        let layoutIndex = 0;
        let layoutOffset = 0;
        list.forEach(section => {
            layoutList.push({
                index: layoutIndex,
                length: headerHeight,
                offset: layoutOffset,
            });
            layoutIndex += 1;
            layoutOffset += headerHeight;
            section.data.forEach(() => {
                layoutList.push({
                    index: layoutIndex,
                    length: itemHeight,
                    offset: layoutOffset,
                });
                layoutIndex += 1;
                layoutOffset += itemHeight;
            });
            layoutList.push({
                index: layoutIndex,
                length: 0,
                offset: layoutOffset,
            });
            layoutIndex += 1;
        });

        this.layoutList = layoutList;
    }

将计算出来的数据传给getItemLayout使用(上面把数据全都放在了this.layoutLis中,下面的data没用了,不用管)

_getItemLayout(data, index) {
        let layout = this.layoutList.filter(n => n.index == index)[0];
        return layout;
    }

点击右侧字母定位

_onSectionselect = (k) => {
        this.sectionList.scrollToLocation(
            {
                sectionIndex: k,
                itemIndex: 0,
                viewOffset: HEADER_HEIGHT,
            }
        );
    }

效果图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值