Flutter如何实现点击AppBar筛选图标弹出1/3宽度浮层覆盖全屏页面
Flutter 实现点击AppBar弹出1/3宽度筛选层方案
实现核心逻辑
你可以直接用Flutter内置的showGeneralDialog实现该需求,该组件可以自定义弹出层的尺寸、位置、动画,完全不需要依赖第三方库。
具体实现步骤
- 在AppBar的actions配置项中添加筛选图标按钮,绑定点击触发弹出层的事件
- 调用
showGeneralDialog构建弹出层,通过MediaQuery获取屏幕宽度,设置筛选层宽度为屏幕宽度的1/3 - 可自定义入场/退场动画,以及点击蒙层关闭的交互逻辑
可运行示例代码
import 'package:flutter/material.dart'; class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('首页'), actions: [ // 筛选图标按钮 IconButton( icon: const Icon(Icons.filter_alt), onPressed: () => _showFilterDialog(context), ) ], ), body: const Center(child: Text('页面主体内容')), ); } // 弹出筛选层方法 void _showFilterDialog(BuildContext context) async { // 接收筛选层返回的参数 final filterResult = await showGeneralDialog( context: context, // 点击蒙层是否关闭 barrierDismissible: true, barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel, // 蒙层颜色 barrierColor: Colors.black.withOpacity(0.5), // 动画时长 transitionDuration: const Duration(milliseconds: 200), pageBuilder: (BuildContext buildContext, Animation animation, Animation secondaryAnimation) { return Align( // 筛选层对齐到屏幕右侧,要左对齐改Alignment.centerLeft即可 alignment: Alignment.centerRight, child: Container( // 宽度设为屏幕1/3 width: MediaQuery.of(context).size.width / 3, height: double.infinity, color: Colors.white, // 筛选层内部内容自己实现 child: Column( children: [ const Padding( padding: EdgeInsets.all(16), child: Text('筛选条件', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), ), // 下面加你自己的筛选表单组件 ListTile(title: const Text('条件1'), onTap: () => Navigator.pop(context, '条件1')), ListTile(title: const Text('条件2'), onTap: () => Navigator.pop(context, '条件2')), ], ), ), ); }, // 可选:添加从右侧滑入的动画 transitionBuilder: (context, anim, anim2, child) { return SlideTransition( position: Tween<Offset>(begin: const Offset(1, 0), end: Offset.zero).animate(anim), child: child, ); }, ); // 拿到筛选结果后处理你的业务逻辑 if (filterResult != null) { debugPrint('选中的筛选条件:$filterResult'); } } }
注意事项
- 如果需要筛选层居中展示,只需把
Align的alignment改为Alignment.center,同时给Container设置固定高度即可 - 如果你的项目全局使用了GetX等状态管理框架,也可以用对应框架提供的对话框组件实现,核心逻辑都是控制弹出层宽度为屏幕1/3
- 要是你不需要自定义动画,也可以直接用
showDialog组件包裹Align实现,只是动画默认是缩放效果
内容的提问来源于stack exchange,提问作者satheesh ck
相关产品推荐
相关产品推荐

