如何移除Flutter应用中Card组件的高亮闪烁效果?
Flutter待办应用:移除Card点击高亮及解决圆角溢出问题
问题根源
你遇到的闪烁高亮是CheckboxListTile自带的点击波纹效果,而高亮溢出圆角是因为该组件内部的InkWell没有继承Card的圆角裁剪,波纹会超出Card的边界绘制。
解决方案
方案一:完全移除点击高亮(推荐)
直接替换CheckboxListTile为自定义Row组件,仅保留Checkbox和文本的交互,彻底消除多余的波纹效果:
// 替换原Dismissible的child部分 child: Card( color: Colors.grey[900], child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( children: [ Checkbox( value: items[index].isCompleted, onChanged: (value) { setState(() { items[index].isCompleted = value!; }); }, activeColor: Colors.grey[600], checkColor: Colors.grey[200], ), const SizedBox(width: 12), Expanded( child: Text( items[index].task, style: TextStyle( color: items[index].isCompleted ? Colors.grey[600] : Colors.grey[200], decoration: items[index].isCompleted ? TextDecoration.lineThrough : TextDecoration.none, decorationColor: items[index].isCompleted ? Colors.grey[200] : null ), ), ), ], ), ), ),
方案二:保留Tile点击交互,修复圆角溢出并隐藏高亮
如果需要保留点击整个Tile切换复选框的功能,可通过InkWell包裹CheckboxListTile,设置透明波纹并匹配Card圆角:
// 替换原Dismissible的child部分 child: Card( color: Colors.grey[900], child: InkWell( // 匹配Card默认圆角(默认是12) borderRadius: BorderRadius.circular(12), // 隐藏波纹和高亮 splashColor: Colors.transparent, highlightColor: Colors.transparent, onTap: () { setState(() { items[index].isCompleted = !items[index].isCompleted; }); }, child: CheckboxListTile( title: Text( items[index].task, style: TextStyle( color: items[index].isCompleted ? Colors.grey[600] : Colors.grey[200], decoration: items[index].isCompleted ? TextDecoration.lineThrough : TextDecoration.none, decorationColor: items[index].isCompleted ? Colors.grey[200] : null ), ), value: items[index].isCompleted, onChanged: (value) { setState(() { items[index].isCompleted = value!; }); }, controlAffinity: ListTileControlAffinity.leading, activeColor: Colors.grey[600], checkColor: Colors.grey[200], contentPadding: const EdgeInsets.symmetric(horizontal: 16), ), ), ),
修改后的完整代码
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: Home(), ); } } class Home extends StatefulWidget { const Home({super.key}); @override State<Home> createState() => _HomeState(); } class _HomeState extends State<Home> { List<TodoItem> items = []; TextEditingController textController = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.grey[800], appBar: AppBar( backgroundColor: Colors.grey[900], title: Text( 'To Do List', style: TextStyle(color: Colors.grey[200]), ), centerTitle: true, ), body: Padding( padding: const EdgeInsets.fromLTRB(30, 40, 30, 0), child: Column( children: [ Expanded( child: ListView.builder( itemCount: items.length, itemBuilder: (context, index) { return Dismissible( key: Key(items[index].task), direction: DismissDirection.endToStart, onDismissed: (direction) { setState(() { items.removeAt(index); }); }, background: Container( alignment: AlignmentDirectional.centerEnd, child: const Padding( padding: EdgeInsets.only(right: 10), child: Icon( Icons.delete, color: Colors.grey[200], ), ), ), // 使用方案一的自定义Row child: Card( color: Colors.grey[900], child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( children: [ Checkbox( value: items[index].isCompleted, onChanged: (value) { setState(() { items[index].isCompleted = value!; }); }, activeColor: Colors.grey[600], checkColor: Colors.grey[200], ), const SizedBox(width: 12), Expanded( child: Text( items[index].task, style: TextStyle( color: items[index].isCompleted ? Colors.grey[600] : Colors.grey[200], decoration: items[index].isCompleted ? TextDecoration.lineThrough : TextDecoration.none, decorationColor: items[index].isCompleted ? Colors.grey[200] : null ), ), ), ], ), ), ), ); }, ), ), ], ), ), floatingActionButton: SizedBox( height: 75, width: 75, child: FloatingActionButton( onPressed: () { _showAddItemDialog(context); }, backgroundColor: Colors.grey[900], child: const Icon( Icons.add, color: Colors.grey[200], size: 50, ), ), ), ); } Future<void> _showAddItemDialog(BuildContext context) async{ return showDialog( context: context, builder: (BuildContext context) { return AlertDialog( backgroundColor: Colors.grey[900], title: const Text( 'Add an item', style: TextStyle(color: Colors.grey[200]), ), content: TextField( controller: textController, style: const TextStyle(color: Colors.grey[200]), decoration: const InputDecoration( labelText: 'Type here...', labelStyle: TextStyle(color: Colors.grey[400]), ), ), actions: [ TextButton( onPressed: () { setState(() { if (textController.text.isNotEmpty) { items.add(TodoItem(task: textController.text, isCompleted: false)); textController.clear(); } }); Navigator.of(context).pop(); }, child: const Text( 'Add', style: TextStyle(color: Colors.grey[200]), ), ), ], ); }, ); } } class TodoItem { final String task; bool isCompleted; TodoItem({required this.task, required this.isCompleted}); }
内容的提问来源于stack exchange,提问作者DominikZ
相关产品推荐
相关产品推荐

