I have just recently started learning Flutter and came across this problem.
I built a simple to do app with Dart and I can’t find how to remove the ‘blinking’ effect on the card.
I’ve tried experimenting with InkWell but it doesn’t do much for me unfortunately.
I also don’t get why it overflows the corners (which looks ugly).
I’ve tried several emulators and physical devices.
The widget which is causing this issue:
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: Padding(
padding: const EdgeInsets.only(right: 10),
child: Icon(
Icons.delete,
color: Colors.grey[200],
),
),
),
child: Card(
color: Colors.grey[900],
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],
),
),
);
},
),
)
Full code:
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: 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: Padding(
padding: const EdgeInsets.only(right: 10),
child: Icon(
Icons.delete,
color: Colors.grey[200],
),
),
),
child: Card(
color: Colors.grey[900],
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],
),
),
);
},
),
),
],
),
),
floatingActionButton: SizedBox(
height: 75,
width: 75,
child: FloatingActionButton(
onPressed: () {
_showAddItemDialog(context);
},
backgroundColor: Colors.grey[900],
child: 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: Text(
'Add an item',
style: TextStyle(color: Colors.grey[200]),
),
content: TextField(
controller: textController,
style: TextStyle(color: Colors.grey[200]),
decoration: 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: Text(
'Add',
style: TextStyle(color: Colors.grey[200]),
),
),
],
);
},
);
}
}
class TodoItem {
final String task;
bool isCompleted;
TodoItem({required this.task, required this.isCompleted});
}
2
Answers
The highlighting effect you are seeing is the default material visual reaction.
You can disable it for a specific widget by overriding the theme for that widget only, or you can disable it entirely in your app
Here is how you can hide(making it transparent) it only for your widget :
If you only want to make the splash effect clipped to the rounded edges, set
clipBehavior: Clip.antiAlias
to theCard
:To completely remove the splash effect, wrap the
CheckboxListTile
withTheme
and give thisThemeData
:NOTE: Without setting
splashFactory: NoSplash.splashFactory
, it will leave a small splash effect when clicked.