如何在Flutter中实现iOS系统自带的搜索界面效果与布局
Flutter实现iOS原生搜索栏滚动联动效果方案
你说的这个iOS原生搜索交互,核心是滚动时搜索栏吸顶、顶部导航栏随滚动偏移折叠的效果,不需要引入第三方依赖,用Flutter自带的Sliver系列组件就能实现,具体方案如下:
核心实现思路
整个布局基于CustomScrollView搭建,用Sliver组件的滚动联动能力实现三个核心交互:
- 顶部导航栏随列表上滑逐渐折叠隐藏
- 搜索栏滚动到顶部时固定吸顶
- 列表内容正常跟随手势滚动
具体实现步骤
1. 自定义吸顶搜索栏代理
首先继承SliverPersistentHeaderDelegate实现搜索栏的吸顶逻辑,控制搜索栏的最小/最大高度,滚动时保持布局稳定:
class SearchBarHeaderDelegate extends SliverPersistentHeaderDelegate { final double height; final Widget child; SearchBarHeaderDelegate({required this.height, required this.child}); @override double get minExtent => height; @override double get maxExtent => height; @override Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { return SizedBox.expand(child: child); } @override bool shouldRebuild(covariant SearchBarHeaderDelegate oldDelegate) { return height != oldDelegate.height || child != oldDelegate.child; } }
2. 组装完整页面布局
把导航栏、搜索栏、列表都放到CustomScrollView的slivers数组中,配置对应的滚动属性:
class IOSSearchDemoPage extends StatefulWidget { const IOSSearchDemoPage({super.key}); @override State<IOSSearchDemoPage> createState() => _IOSSearchDemoPageState(); } class _IOSSearchDemoPageState extends State<IOSSearchDemoPage> { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: CustomScrollView( slivers: [ // 顶部导航栏,随滚动折叠 SliverAppBar( floating: true, snap: true, expandedHeight: 56, backgroundColor: Colors.white, elevation: 0, title: const Text("搜索", style: TextStyle(color: Colors.black, fontSize: 17)), ), // 吸顶搜索栏 SliverPersistentHeader( pinned: true, delegate: SearchBarHeaderDelegate( height: 52, child: Container( color: Colors.white, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), child: const TextField( decoration: InputDecoration( hintText: "搜索内容", hintStyle: TextStyle(color: Colors.grey, fontSize: 15), prefixIcon: Icon(Icons.search, color: Colors.grey, size: 20), filled: true, fillColor: Color(0xFFF2F2F7), border: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10)), borderSide: BorderSide.none, ), contentPadding: EdgeInsets.symmetric(vertical: 8), ), ), ), ), ), // 下方列表内容 SliverList( delegate: SliverChildBuilderDelegate( (context, index) => ListTile( title: Text("测试项 $index"), ), childCount: 80, ), ) ], ), ); } }
3. 可选效果优化
如果需要完全对齐iOS原生的交互细节,可以补充以下调整:
- 监听
CustomScrollView的滚动偏移,动态调整导航栏的透明度、搜索栏的上下内边距,实现滚动时的平滑过渡 - 给TextField添加点击事件,点击后跳转到独立的搜索结果页,配合模糊背景实现和iOS一致的搜索跳转效果
- 输入内容时实时过滤列表数据,更新
SliverList的展示内容
内容的提问来源于stack exchange,提问作者Akbar Pulatov
相关产品推荐
相关产品推荐

