Flutter如何为bottom navigation bar添加onPressed()点击功能
基于Gesture实现图标式底部导航栏点击交互
你不需要改动原有导航栏的布局、动画逻辑,只需要把手势响应部分替换为GestureDetector,同时在点击回调里绑定自定义的点击事件即可,具体实现如下:
核心修改点
- 删掉原代码里带材质水波纹效果的
InkWell,换成纯手势识别的GestureDetector,完全靠Gesture能力处理点击交互,匹配你的实现需求 onTap回调里先保留原来更新currentIndex的状态刷新代码,再往下追加每个图标对应的点击逻辑即可,直接通过索引判断当前点击的是哪个导航项,对应写页面跳转、业务触发代码就行- 原有的选中态顶部指示条动画、图标颜色切换逻辑完全不需要调整,不会影响现有展示效果
修改后完整代码
bottomNavigationBar: Container( margin: const EdgeInsets.all(20), height: size.width * .150, decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(.15), blurRadius: 30, offset: const Offset(0, 10), ), ], borderRadius: BorderRadius.circular(20), ), child: ListView.builder( itemCount: 4, scrollDirection: Axis.horizontal, padding: EdgeInsets.symmetric(horizontal: size.width * .024), itemBuilder: (context, index) => GestureDetector( // 手势点击回调 onTap: () { setState(() { currentIndex = index; }); // 在此处绑定每个导航图标对应的自定义点击逻辑 // 按索引区分不同导航项的操作即可 switch(index) { case 0: // 第一个图标点击逻辑,例如跳转首页 break; case 1: // 第二个图标点击逻辑,例如跳转搜索页 break; case 2: // 第三个图标点击逻辑,例如跳转消息页 break; case 3: // 第四个图标点击逻辑,例如跳转个人中心页 break; } }, behavior: HitTestBehavior.opaque, // 保证整个导航项区域都能响应点击,不会出现空白点了没反应的问题 child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AnimatedContainer( duration: const Duration(milliseconds: 1500), curve: Curves.fastLinearToSlowEaseIn, margin: EdgeInsets.only( bottom: index == currentIndex ? 0 : size.width * .029, right: size.width * .0422, left: size.width * .0422, ), width: size.width * .128, height: index == currentIndex ? size.width * .014 : 0, decoration: const BoxDecoration( color: Colors.orangeAccent, borderRadius: BorderRadius.vertical( bottom: Radius.circular(10), ), ), ), Icon( listOfIcons[index], size: size.width * .076, color: index == currentIndex ? Colors.orangeAccent : Colors.black, ), SizedBox(height: size.width * .03), ], ), ), ), ),
补充:如果需要点击时的轻量触觉反馈,可以在
onTap回调最开头加入HapticFeedback.lightImpact();,不需要额外引入其他依赖。
内容的提问来源于stack exchange,提问作者Nehal Hosalikar
相关产品推荐
相关产品推荐

