skip to Main Content

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.

this is what i mean

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


  1. 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 :

    Theme(
      data: ThemeData(
        splashColor: Colors.transparent,
        highlightColor: Colors.transparent,
      ),
      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],
        ),
      ),
    )
    
    Login or Signup to reply.
  2. If you only want to make the splash effect clipped to the rounded edges, set clipBehavior: Clip.antiAlias to the Card:

    Card(
      clipBehavior: Clip.antiAlias,
      // ...
    )
    

    To completely remove the splash effect, wrap the CheckboxListTile with Theme and give this ThemeData:

    Theme(
      data: ThemeData(
        splashFactory: NoSplash.splashFactory,
        splashColor: Colors.transparent,
        highlightColor: Colors.transparent,
      ),
      child: CheckboxListTile(
        // ...
      ),
    )
    

    NOTE: Without setting splashFactory: NoSplash.splashFactory, it will leave a small splash effect when clicked.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search