React Native 仿微信通讯录右侧字母快捷操作区

其实也不能说仿微信,大部分通讯录都一样,先来看两张效果图第一张是微信、第二张是我写的简单介绍一下功能点1、好友排序 2、点击右侧快捷操作区,相应跳转到所属通讯录区域 3、ScrollView 在滑动过程中自动匹配右侧字母分类,同时作出UI更新详细讲讲好友信息数据结构let typeList = [ { nickname: '曾泰', picture: '', letter: 'Z' },
摘要由CSDN通过智能技术生成

其实也不能说仿微信,大部分通讯录都一样,先来看两张效果图

第一张是微信、第二张是我写的

简单介绍一下功能点

1、好友排序
2、点击右侧快捷操作区,相应跳转到所属通讯录区域
3、ScrollView 在滑动过程中自动匹配右侧字母分类,同时作出UI更新

详细讲讲

好友信息数据结构

let typeList = [
  { nickname: '曾泰', picture: '', letter: 'Z' },
  { nickname: '狄仁杰', picture: '', letter: 'D' },
  { nickname: '李元芳', picture: '', letter: 'L' },
  ......
]

右侧操作栏数据结构

let addressAllList = [
  { title: 'A', number: 0, scrollHeight: 0 },
  { title: 'B', number: 0, scrollHeight: 0 },
  { title: 'C', number: 0, scrollHeight: 0 },
  { title: 'D', number: 0, scrollHeight: 0 },
  { title: 'E', number: 0, scrollHeight: 0 },
  { title: 'F', number: 0, scrollHeight: 0 },
  ......
】

1、好友排序

这个是基本操作,没什么可说的,为了功能的完整性,纯当做记录吧

/** 对列表信息进行排序 放在saga中进行处理 */
sortFriend () {
  this.friendListSource = typeList.sort((a, b) => { return a.letter.localeCompare(b.letter) })
}

2、点击右侧快捷操作区,相应跳转到所属通讯录区域

原理是这样的,通过计算获得,每个字母区间所包含的好友个数,相应的就能得到该字幕区间的高度Height值,如果有了ScrollView的y值和每一行的高度值,那么我们就能精确的算出点击每个字母我们需要跳转到的绝对位置,嗯

但前提是,我们需要精确的得到这两个值

componentDidMount () {
  /** 获取列表组件高度 */
  const that = this
  setTimeout(function () {
    that.refs.friendArea.measure((x, y, width, height, left, top) => {
      console.log('好友列表从高度' + y + '开始渲染***************')
      that.setState({ y })
    })
    that.refs.friendItem.measure((x, y, width, height, left, top) => {
      console.log('列表Item高度为' + height + '***************')
      that.rowHeight = height
      that.setState({ rowHeight: height })
    })
  })
}

接下来,我们就开始定量计算了

/** 右侧通讯录 */
sortAddress () {
  /**
   * 计算每层个数
   */
  let tempList = addressAllList
  typeList.map((item) => {
    addressAllList.map((element, index) => {
      if (element.title === item.letter) {
        let { number } = tempList[index]
        // console.log('出现一个相同项' + item.letter)
        tempList.splice(index, 1, { ...tempList[index], number: number + 1 })
      }
    })
  })
  /**
   * 计算每层y
   */
  tempList.map((item, index) => {
    let change = {}
    if (index === 0) {
      change = { ...item, scrollHeight: this.state.y }
    } else {
      const { scrollHeight, number } = this.addressListSource[index - 1]
      change = { ...item, scrollHeight: scrollHeight + number * this.state.rowHeight }
    }
    this.addressListSource.push(change)
  })
  // console.log(this.addressListSource)
  this.setState({ addressList: this.addressListSource })
}

界面操作呢????

this.refs.scroll.scrollTo({ y: scrollHeight, animated: true })} 就好了

<View style={
   { position: 'absolute', top: y, right: px2dp(6) }}>
  { addressList.map((item, index) => {
    const { title, number, scrollHeight } = item
    return (number !== 0 &&
    <TouchableWithoutFeedback onPress={() => this.refs.scroll.scrollTo({ y: scrollHeight, animated: true })} key
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值