Dismissible container and ListView item not the same size

Question

Asked by Rohith N on November 02, 2021 (source).

I just started learning flutter and am trying to build a todo app, the problem I encountered was the Dismissible container and the todo list view item have different heights and after trying everything I still couldn't fix it, the next problem was that the todo item would be dismissed from left to right whereas the container would go up. Any help would be much appreciated. My code:

class _HomePageState extends State<HomePage> {
  List todos = [];
  List<TextEditingController> _titleController = [];
  List<TextEditingController> _detailController = [];

  @override
  void initState() {
    super.initState();
    todos.add('');
    _titleController.add(TextEditingController());
    _detailController.add(TextEditingController());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          width: double.infinity,
          padding: const EdgeInsets.symmetric(
            horizontal: 24.0,
          ),
          color: const Color(0xfff6f6f6f6),
          child: Stack(
            children: [
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Container(
                    margin: const EdgeInsets.only(bottom: 32.0, top: 32.0),
                    child: const Text(
                      "Reminders",
                      style: TextStyle(
                        fontSize: 25.0,
                        fontWeight: FontWeight.bold
                      ),
                    ),
                  ),
                  Expanded(
                    child: ListView.builder(
                      itemCount: todos.length,
                      physics: const BouncingScrollPhysics(),
                      itemBuilder: (BuildContext context, int index) {
                        return Dismissible(
                            background: buildActionSwipeLeft(),
                            onDismissed: (direction) {
                              setState(() {
                                todos.removeAt(index);
                                _titleController.removeAt(index);
                                _detailController.removeAt(index);
                                DismissDirection.startToEnd;
                              });
                            },
                            direction: DismissDirection.startToEnd,
                            key: Key(todos[index]),
                            child: Padding(
                              padding: const EdgeInsets.only(
                                bottom: 15.0
                              ),
                              child: Card(
                                color: Colors.white,
                                shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(16),
                                ),
                                elevation: 4,
                                child: Container(
                                    width: double.infinity,
                                    padding: const EdgeInsets.symmetric(
                                        vertical: 15.0,
                                        horizontal: 24.0
                                    ),
                                    margin: const EdgeInsets.only(
                                      bottom: 20.0,
                                    ),
                                    child: Column(
                                      crossAxisAlignment: CrossAxisAlignment.start,
                                      children: [
                                        TextField(
                                          cursorColor: Colors.black,
                                          controller: _titleController[index],
                                          style: const TextStyle(
                                              fontSize: 22.0,
                                              fontWeight: FontWeight.bold
                                          ),
                                          decoration: const InputDecoration(
                                            hintText: "Enter a title",
                                            border: InputBorder.none,
                                          ),
                                        ),
                                        const Divider(
                                          color: Colors.black,
                                        ),
                                        Padding(
                                          padding: const EdgeInsets.only(top: 0.0),
                                          child: TextField(
                                            controller: _detailController[index],
                                            style: TextStyle(
                                              fontSize: 20.0,
                                              color: Colors.grey[900],
                                            ),
                                            cursorColor: Colors.black,
                                            maxLines: null,
                                            decoration: const InputDecoration(
                                                hintText: "Enter the description",
                                                label: Text("description"),
                                                border: InputBorder.none
                                            ),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                              ),
                            ),
                          );
                      },
                    ),
                  )
                ],
              ),
              Positioned(
                bottom: 24.0,
                right: 0.0,
                child: GestureDetector(
                  onTap: () {
                    setState(() {
                      todos.add('');
                      _titleController.add(TextEditingController());
                      _detailController.add(TextEditingController());
                    });
                  },
                  child: Container(
                  width: 60.0,
                  height: 60.0,
                  decoration: BoxDecoration(
                    color: Colors.black87,
                    borderRadius: BorderRadius.circular(20.0),
                  ),
                  child: const Icon(Icons.add, color: Colors.white, size: 35.0),
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

Widget buildActionSwipeLeft() => Container(
  alignment: Alignment.centerLeft,
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(20.0),
    color: Colors.red,
  ),
  padding: const EdgeInsets.symmetric(horizontal: 30),
  child: const Icon(Icons.delete, color: Colors.white, size: 30),
);

Answer

Question answered by Davis (source).


class _HomePageState extends State<HomePage> {
  List todos = [];
  List<TextEditingController> _titleController = [];
  List<TextEditingController> _detailController = [];

  @override
  void initState() {
    super.initState();
    todos.add('');
    _titleController.add(TextEditingController());
    _detailController.add(TextEditingController());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          width: double.infinity,
          padding: const EdgeInsets.symmetric(
            horizontal: 24.0,
          ),
          color: const Color(0xfff6f6f6f6),
          child: Stack(
            children: [
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Container(
                    margin: const EdgeInsets.only(bottom: 32.0, top: 32.0),
                    child: const Text(
                      "Reminders",
                      style: TextStyle(
                          fontSize: 25.0, fontWeight: FontWeight.bold),
                    ),
                  ),
                  Expanded(
                    child: ListView.builder(
                      itemCount: todos.length,
                      physics: const BouncingScrollPhysics(),
                      itemBuilder: (BuildContext context, int index) {
                        return Stack(
                          clipBehavior: Clip.hardEdge,
                          children: [
                            Padding(
                              padding: const EdgeInsets.only(top:10.0,left: 8.0, right: 8.0),
                              child: buildActionSwipeLeft(),
                            ),
                            Dismissible(
                              onDismissed: (direction) {
                                setState(() {
                                  todos.removeAt(index);
                                  _titleController.removeAt(index);
                                  _detailController.removeAt(index);
                                  DismissDirection.startToEnd;
                                });
                              },
                              direction: DismissDirection.startToEnd,
                              key: UniqueKey(),
                              child: Padding(
                                padding: const EdgeInsets.only(bottom: 15.0),
                                child: Card(
                                  color: Colors.white,
                                  shape: RoundedRectangleBorder(
                                    borderRadius: BorderRadius.circular(16),
                                  ),
                                  elevation: 4,
                                  child: Container(
                                    width: double.infinity,
                                    padding: const EdgeInsets.symmetric(
                                        vertical: 15.0, horizontal: 24.0),
                                    margin: const EdgeInsets.only(
                                      bottom: 20.0,
                                    ),
                                    child: Column(
                                      crossAxisAlignment:
                                          CrossAxisAlignment.start,
                                      children: [
                                        TextField(
                                          cursorColor: Colors.black,
                                          controller: _titleController[index],
                                          style: const TextStyle(
                                              fontSize: 22.0,
                                              fontWeight: FontWeight.bold),
                                          decoration: const InputDecoration(
                                            hintText: "Enter a title",
                                            border: InputBorder.none,
                                          ),
                                        ),
                                        const Divider(
                                          color: Colors.black,
                                        ),
                                        Padding(
                                          padding:
                                              const EdgeInsets.only(top: 0.0),
                                          child: TextField(
                                            controller:
                                                _detailController[index],
                                            style: TextStyle(
                                              fontSize: 20.0,
                                              color: Colors.grey[900],
                                            ),
                                            cursorColor: Colors.black,
                                            maxLines: null,
                                            decoration: const InputDecoration(
                                                hintText:
                                                    "Enter the description",
                                                label: Text("description"),
                                                border: InputBorder.none),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                ),
                              ),
                            )
                          ],
                        );
                      },
                    ),
                  )
                ],
              ),
              Positioned(
                bottom: 24.0,
                right: 0.0,
                child: GestureDetector(
                  onTap: () {
                    setState(() {
                      todos.add('');
                      _titleController.add(TextEditingController());
                      _detailController.add(TextEditingController());
                    });
                  },
                  child: Container(
                    width: 60.0,
                    height: 60.0,
                    decoration: BoxDecoration(
                      color: Colors.black87,
                      borderRadius: BorderRadius.circular(20.0),
                    ),
                    child:
                        const Icon(Icons.add, color: Colors.white, size: 35.0),
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

Widget buildActionSwipeLeft() => Container(
  height: 180,
      alignment: Alignment.centerLeft,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(20.0),
        color: Colors.red,
      ),
      padding: const EdgeInsets.only(left: 30),
      child: const Icon(Icons.delete, color: Colors.white, size: 30),
    );


Achieving this has a disadvantage of loosing a few animation. Will research more:

DART FLUTTER
SHARE: