【Flutter】微信项目实战【07】 通讯录界面搭建(下)

1. 写在前面

上篇文章中已经对微信通讯录界面进行了列表部分,包括组头的设置、怎么显示隐藏合并组的代码实现,那么今天就继续来写微信实战项目的通讯录界面最复杂的索引条部分!

最终效果.gif

2. 页面布局

首先索引条是在列表之上的,也就是布局来说是悬浮的,那么我们可以使用Stack来布局,然后在封装一个索引条IndexBar

通讯录布局

3. 索引条封装

索引条是需要改变状态的,索引我们使用StatefulWidget,方便后续的状态的改变,以根据状态的改变来改变列表的显示。索引是由两部分组成的:

  • 指示器:就是拖动索引条,前面的放大器部分,里面显示对应的索引字母。
  • 索引条:显示分组的名称字母,这个要根据鼠标的移动,来改变指示器的位置和显示的文字。

大致的代码布局如下所示:

索引条代码结构

索引条是悬浮的,所以需要定位它的位置,这里使用Positioned来定位。这里设置索引条的高度是屏幕高的一半,距离屏幕的顶部距离是屏幕高度的八分之一,宽度为 120。

索引条

3.1 指示器

指示器这里和索引条是一体的,只是改变一下位置就可以了。

//指示器
          Container(
            alignment: Alignment(0,_indicatorY),
            width: 100,
            // color: Colors.red,
            child: _indicatorHidden?null:Stack(
              alignment: const Alignment(-0.2,0),
              children: [
               const Image(image: AssetImage("images/气泡.png"),width: 60,),
                Text(_indicatorText,style: const TextStyle(fontSize: 18,color: Colors.white),)
              ],
            ),
          ),

这里指示器外面是用Container包裹,里面是使用了Stack来包裹一个放大镜🔍的图片,再把需要显示的Text置顶,以此来达到我们需要的效果。
字母索引我们这里是使用一个 List,遍历本地写的一个字母 LIst 来参加字母的 widget,具体代码如下所示:

在这里插入图片描述

3.2 索引条

索引条是需要响应手势的,所以用GestureDetector来包裹起来。

针对鼠标的拖动时、离开时的回调方法来处理不同的状态。

我们要定位索引条字母的位置,根据鼠标移动的位置来改变,指示器的移动位置,这就得拿到坐标才可以。系统还真提供了这样一个方法,可以通过RenderBox来找到当前的位置。获取的代码如下所示:

int getIndexItem(BuildContext context,Offset globalPosition){
  //拿到当前盒子
  RenderBox box = context.findRenderObject() as RenderBox;
  //拿到y值,当前位置到部件原点(部件左上角)的距离(x,y)
  var y = box.globalToLocal(globalPosition).dy;
  //算出字符高度
  var itemHeight = screenHeight(context)/2/INDEX_WORDS.length;
  int index = y ~/itemHeight.clamp(0, INDEX_WORDS.length-1);//~取整,设置取整范围clamp
  print("${INDEX_WORDS[index]}");
  return index;
}

这里封装了一个方法,来获取每个字母的位置,然后在数据移动的相关回调方法里面直接调用就可以了。具体的处理逻辑如下图所示:

字母索引

那么现在我们来看看,鼠标移动是否可以达到改变指示器的效果呢?

索引条

从上面的效果图来看,已经基本满足了我们的需求,现在还有一个功能需要实现,就是点击索引对应的字母,让列表滚动起来,而且滚动的效果是,我点击那个字母,所在组就置顶。那么现在就去实现一下吧!

3.3 列表置顶

那么实现的思路,就是我们得知道整个列表对应的字母的偏移量,根据对应字母的偏移量来对列表进行偏移就可以了。那么该如何去计算这个偏移量呢?计算的时机是在什么时候呢?

我们肯定不能动态的去计算吧,不能你点击一次就计算一下,应该是界面进来的时候就是已经计算好了的。

final Map _groupOffsetMap = {
    INDEX_WORDS[0]:0.0,
    INDEX_WORDS[0]:0.0,
  };

我们这里使用一个字典也就是 Map来存放对应字母的偏移量,在处理组头的时候就顺便一起计算,存在map 里面,这样我点击的是那个字母或者鼠标滚动到对应的字母,就改变偏移量就 OK 了!

//索引条
          IndexBar(indexBarCallBack:(String str){
            if(_groupOffsetMap[str]!=null){

              _scrollController.animateTo(_groupOffsetMap[str],
                  duration: const Duration(microseconds: 100),
                  curve: Curves.easeIn);
            }

          }
          ),

这里IndexBar的回调方法indexBarCallBack,在其回调方法里面对字典里面的对应字母值进行判断,然后控制器去控制对应的偏移量。完成效果如下:

索引条效果

以上就是本次博客的全部内容,欢迎大家留言交流。更详细的代码请移步这里👉GitHub项目地址

3. 写在后面

关注我,更多内容持续输出

【Flutter】基础组件【01】Text

【Flutter】基础组件【02】Container

【Flutter】基础组件【03】Scaffold

【Flutter】基础组件【04】Row/Column

【Flutter】基础组件【05】Icon

【Flutter】基础组件【06】Image

【Flutter】基础组件【07】Appbar

【Flutter】基础组件【08】BottomNavigationBar

【Flutter】基础组件【09】Button

  • [项目实战合集]

【Flutter】微信项目实战【01】基本框架搭建

【Flutter】微信项目实战【02】我的界面搭建(上)

【Flutter】微信项目实战【03】我的界面搭建(下)

【Flutter】微信项目实战【04】发现界面搭建

【Flutter】微信项目实战【05】 通讯录界面搭建(上)

【Flutter】微信项目实战【06】 通讯录界面搭建(中)

🌹 喜欢就点个赞吧👍🌹

🌹 觉得有收获的,可以来一波 收藏+关注,以免你下次找不到我😁🌹

🌹欢迎大家留言交流,批评指正,转发请注明出处,谢谢支持!🌹

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡卡西Sensei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值