You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何移除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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 18:40:55