Flutter中ListTile的color与hoverColor超出父容器溢出问题怎么解决?
触发原因
ListTile的颜色属性(color、hoverColor、点击水波纹颜色等)均由内部的InkResponse组件实现绘制,Ink系列组件的绘制逻辑为向上寻找最近的父级Material组件作为绘制画布,默认不会主动将绘制内容剪裁到自身组件的边界,当父组件未设置剪裁规则时,颜色填充就会超出ListTile的自身范围。- 示例代码中直接使用
GestureDetector包裹ListTile,GestureDetector本身不提供独立的Material绘制画布,ListTile内部Ink效果的绘制范围会直接继承更上层的Material(如Scaffold根节点的Material)尺寸,进一步加重溢出问题。 ListTile默认存在水平contentPadding内边距,若父组件尺寸未匹配ListTile的实际绘制范围,也会出现颜色超出预期显示区域的问题。
修复方案
以下三种方案任选一种即可,改动量从小到大依次排列:
方案1:添加ClipRect强制剪裁
在ListTile外层包裹ClipRect组件,强制将子组件的绘制内容剪裁到自身边界:
@override Widget build(BuildContext context) { return ListView.builder( itemCount: titles.length, itemBuilder: (context, index) { return GestureDetector( onSecondaryTap: () { print('clicked index : $index'); }, // 新增ClipRect包裹ListTile child: ClipRect( child: ListTile( hoverColor: Colors.amber, title: Padding( padding: EdgeInsets.only(bottom: 0, top: 0), child: Text( titles[index], style: TextStyle( fontWeight: FontWeight.bold, color: dark, fontSize: 14, ), ), ), subtitle: Padding( padding: const EdgeInsets.only(bottom: 0, top: 0, left: 0, right: 0), child: Text( subtitles[index], style: TextStyle( color: _statusColor(subtitles[index]), fontSize: 11, ), ), ), leading: CircleAvatar( radius: 25, backgroundImage: NetworkImage("https://images.unsplash.com/photo-1547721064-da6cfb341d50"), ), ), ), ); }); }
方案2:为ListTile设置shape属性
给ListTile添加shape属性,指定绘制形状的同时会自动触发内容剪裁,无需新增外层组件:
ListTile( hoverColor: Colors.amber, // 新增shape属性,即使是圆角为0的矩形也可以生效 shape: RoundedRectangleBorder(borderRadius: BorderRadius.zero), // 其余原有属性保持不变 ... )
方案3:替换GestureDetector为InkWell
将外层的GestureDetector替换为InkWell,同时将hover相关属性转移到InkWell上,统一管理交互效果,从根源避免绘制溢出:
@override Widget build(BuildContext context) { return ListView.builder( itemCount: titles.length, itemBuilder: (context, index) { // 替换GestureDetector为InkWell,外层新增Material提供绘制画布 return Material( color: Colors.transparent, child: InkWell( onSecondaryTap: () { print('clicked index : $index'); }, // hoverColor转移到InkWell上 hoverColor: Colors.amber, child: ListTile( // 删掉原有hoverColor属性,其余属性保持不变 ... ), ), ); }); }
内容的提问来源于stack exchange,提问作者Hakan Yıldız
相关产品推荐
相关产品推荐

