Flutter ExpansionTile双操作配置及尾随图标隐藏问题
解决ExpansionTile的两个自定义需求
一、实现点击尾随图标展开,点击其他区域跳转
ExpansionTile默认点击整个tile都会触发展开/收起,要区分点击区域得这么改:
- 给每个tile维护独立的展开状态变量
_isExpanded - 把
leading、title、subtitle包装成可点击区域,点击时执行跳转逻辑 - 自定义
trailing图标,点击这个图标单独切换展开状态,同时将ExpansionTile的expanded属性绑定到状态变量上
二、子项为空时隐藏尾随图标
直接判断子列表长度:如果长度为0,就把trailing设为空组件(比如SizedBox.shrink());否则显示切换展开的图标。
修改后的完整代码
Expanded( child: ListView.builder( itemBuilder: (context, index) { // 每个tile独立维护展开状态 bool _isExpanded = false; final sublist = list[index].sublist; return Card( child: StatefulBuilder( builder: (context, setState) { return ExpansionTile( // 绑定展开状态 expanded: _isExpanded, // 把leading/title/subtitle整合成可点击区域,点击跳转 leading: GestureDetector( onTap: () { // 替换成你的跳转逻辑,比如Navigator.push print('跳转至目标页面'); }, child: Image.asset('images'), ), title: GestureDetector( onTap: () { print('跳转至目标页面'); }, child: Text('Text'), ), subtitle: GestureDetector( onTap: () { print('跳转至目标页面'); }, child: Text('Text'), ), // 根据子列表长度决定是否显示尾随图标 trailing: sublist.isEmpty ? const SizedBox.shrink() : IconButton( icon: Icon( _isExpanded ? Icons.expand_less : Icons.expand_more, ), onPressed: () { setState(() { _isExpanded = !_isExpanded; }); }, ), // 子列表为空时直接传空数组 children: sublist.isEmpty ? [] : [ ListView.builder( itemBuilder: (context, index2) { return Card( child: ListTile( onTap: () => print('test'), leading: Image.asset('images'), title: Text('Text'), subtitle: Text('Text'), ), ); }, itemCount: sublist.length, shrinkWrap: true, padding: const EdgeInsets.all(5), scrollDirection: Axis.vertical, ), ], ); }, ), ); }, itemCount: list.length, shrinkWrap: true, padding: const EdgeInsets.all(5), scrollDirection: Axis.vertical, ), )
额外优化提示
如果觉得多个GestureDetector重复,可以把leading、title、subtitle整个包裹在一个大的GestureDetector里,这样点击tile除尾随图标外的所有区域都会触发跳转,代码更简洁。
内容的提问来源于stack exchange,提问作者Icaroto
相关产品推荐
相关产品推荐

