千家信息网

Flutter仿微信通讯录怎么实现自定义导航条

发表于:2025-11-14 作者:千家信息网编辑
千家信息网最后更新 2025年11月14日,这篇文章主要介绍了Flutter仿微信通讯录怎么实现自定义导航条的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Flutter仿微信通讯录怎么实现自定义导航条文章都会有所收
千家信息网最后更新 2025年11月14日Flutter仿微信通讯录怎么实现自定义导航条

这篇文章主要介绍了Flutter仿微信通讯录怎么实现自定义导航条的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Flutter仿微信通讯录怎么实现自定义导航条文章都会有所收获,下面我们一起来看看吧。

关键点:手势定位滑动、列表定位、手势、列表联动。

准备数据,首先我们需要准备导航目录数据,

List _az = [  "☆",  "A",  "B", "C",  "D",  "E",  "F",  "G", "H",  "I",  "G",  "K", "L",   "M",  "N",  "O", "P",  "Q",  "R",  "S", "T",  "U",  "V", "W",  "X",   "Y", "Z", ];

然后列表数据,列表数据可以让后台给我们排序好,如果后台不给我们排序,我们也可以自己排序进行组装, 这里用到一个插件,根据汉字获取拼音首字母,我们自己就可以对这些数据进行整理排序。

lpinyin: ^2.0.3

数据格式:一个NameBean对应一个字母所在的列表,这是我们存储正式列表数据的格式。

class NameBean {  String? initial;// 字母导航  List? nameList;// 内容列表  NameBean({    this.initial,    this.nameList,  });}/// name : "老李"/// 这里我只放了一个name字段,以后扩展内容只需在这里新增字段就好了class Name {  String? name;  Name({    this.name,  });}

接下来我们先做导航条:

实现思路: 导航条就是一个List列表,点击、滑动、松开会有不同的交互,我们根据不同的交互来进行实现,这里我们会用到官方的GestureDetector组件,专门用来进行手势识别。将每一个item的高度固定,通过手势交互返回的位置数据来进行返回我们想要的目录。比如我的每一个目录高度设置为20.

导航条代码:点击或者移动的时候选中的目录会有一个按压效果,

GestureDetector(  child: Container(      margin: EdgeInsetsDirectional.only(top: 40),      width: 40,      // 导航条      child: ListView.builder(        physics: NeverScrollableScrollPhysics(),        shrinkWrap: true,        itemBuilder: (context, index) {          return SizedBox(            height: 20,            // 这里做了一个按压或移动滑动的触发效果            child: Container(              alignment: Alignment.center,              decoration: BoxDecoration(                  color:                      currentIndex == index ? Colors.redAccent : null,                  shape: BoxShape.circle),              child: Text(                _az[index],                style: TextStyle(                  color: currentIndex == index                      ? Colors.white                      : Colors.black87,                ),              ),            ),          );        },        itemCount: _az.length,      )),      //手指按下触发 竖着划就用onVertica XXX回调  onVerticalDragDown: (DragDownDetails e) {    //打印手指按下的位置(相对于屏幕)    int i = e.localPosition.dy ~/ 20;    // _scrollController.jumpTo(index: i);    setState(() {      currentIndex = i;    });  },  //手指滑动时会触发此回调  onVerticalDragUpdate: (DragUpdateDetails e) {    //用户手指滑动时,更新偏移    int i = e.localPosition.dy ~/ 20;    _az.length;    if (i >= 0 && i <= _az.length - 1) {      if (i != currentIndex) {        setState(() {        // 当前选中的index 默认-1          currentIndex = i;        });        print("滑动 ${_az[i]}");                    }    }  },  // 手指抬起  onTapUp: (e) {    // 手指抬起    setState(() {      currentIndex = -1;    });  },  // 移动取消  onVerticalDragEnd: (e) {    // 移动取消    setState(() {      currentIndex = -1;    });  },)

然后我们可以看到微信在滑动的时候有个字母放大气泡会跟随着手势移动。

实现思路:

气泡和导航条并列,并根据手势位置更新上边距即可,因为我们的导航条的每一个item的高度是固定的,所以我们就可以根据滑动的位置计算出滑动距离顶部的高度,这里气泡可以让UI切个背景图,也可以自己用canvas画一个。

气泡绘制源码:

@overridevoid paint(Canvas canvas, Size size) {  // 原点移到左下角  canvas.translate(size.width / 2, size.height / 2);  Paint paint = Paint()    ..color = Colors.redAccent    ..strokeWidth = 2    ..style = PaintingStyle.fill;  Path path = Path();  // 绘制文字  path.lineTo(0, -size.width / 2);  // path.conicTo(33, -28, 20, 0, 1);  path.arcToPoint(Offset(size.width / 2, 0),      radius: Radius.circular(size.width / 2),      largeArc: true,      clockwise: true);  path.close();  var bounds = path.getBounds();  canvas.save();  canvas.translate(-bounds.width / 2, bounds.height / 2);  canvas.rotate(pi * 1.2);  canvas.drawPath(path, paint);  canvas.restore();  // 绘制文字  var textPainter = TextPainter(      text: TextSpan(          text: text,          style: TextStyle(            fontSize: 24,            foreground: Paint()              ..style = PaintingStyle.fill              ..color = Colors.white,          )),      textAlign: TextAlign.center,      textDirection: TextDirection.ltr);  textPainter.layout();  canvas.translate(-size.width, -size.height / 2);  textPainter.paint(canvas, Offset(-size.width / 2.4, size.height / 1.2));}

导航条、气泡都完成了,接下来就非常简单了,内容的填充我们就不能用ListView了,这里我们需要一个官方的插件: scrollable_positioned_list: ^0.2.3 使用它可以定位到具体的item位置,这样我们就可以进行列表定位和导航条进行联动了。

内容代码:

ScrollablePositionedList.builder(  physics: BouncingScrollPhysics(),  itemScrollController: _scrollController,  itemBuilder: (context, index) {    return Column(      crossAxisAlignment: CrossAxisAlignment.start,      mainAxisSize: MainAxisSize.min,      children: [        Container(          padding: EdgeInsetsDirectional.only(start: 10),          child: Text(dataList[index].initial ?? ""),          color: Colors.grey.shade300,          height: 30,          width: double.infinity,          alignment: Alignment.centerLeft,        ),        Container(          padding: EdgeInsetsDirectional.only(start: 15),          child: ListView.builder(            // 禁用滑动事件            physics: NeverScrollableScrollPhysics(),            shrinkWrap: true,            itemBuilder: (context, cityIndex) {              return InkWell(                child: Container(                  height: 40,                  child: Column(                    children: [                      Expanded(                        child: Container(                          child: Text(dataList[index]                                  .nameList?[cityIndex]                                  .name ??                              ""),                          alignment: Alignment.centerLeft,                        ),                      ),                      Divider(                        height: 0.5,                      )                    ],                  ),                ),                onTap: () {},              );            },            itemCount: dataList[index].nameList?.length,          ),        )      ],    );  },  itemCount: dataList.length,)

ScrollablePositionedList用法基本和ListView一直,只是它多了一个这个方法,可以定位到具体的item。

_scrollController.jumpTo(index: i);

看下最终效果:

关于"Flutter仿微信通讯录怎么实现自定义导航条"这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对"Flutter仿微信通讯录怎么实现自定义导航条"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。

导航 数据 内容 手指 位置 手势 气泡 定位 移动 通讯 通讯录 字母 目录 高度 排序 效果 知识 不同 接下来 代码 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 服务器管理说明 大话2志在四方服务器 成都软件开发pm招聘 镇江公司网络安全准入控制哪家好 胡一天真的会网络安全大赛吗 stm32软件开发入门 数据库为何会账户被锁定 软件开发征税优惠 丰台区网络技术咨询成本价 绝地求生香港服务器下载 数据库中怎么计算长度的 沈阳申鑫软件开发有限公司 山西电力应急软件开发服务价钱 服务器管理中心是干什么的 wifi软件开发工程师 中国邮政软件开发中心领导成员 cs1.6琥珀战队服务器下载 智慧党建数据库建设 数据库一般大几学 可以用哪些软件开发抓包系统 数据库中日期的最大值 93看书软件开发 服务器更换技术协议怎么写 山西启智互动网络技术有限公司 数据库原理介绍 pcs7什么时候需要用服务器 如何让数据库无法注入js 软件开发工程师就是做程序员吗 服务器时间在哪里更改 数据库应用系统需求分期
0