Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Back Button Not Working when implemented a ListView Builder Widget Flutter

I have this code which displays a back button, text, and then a listview builder widget.

When I remove the listview builder widget, the back button works fine, but when I add it back the back button breaks. I don’t know why this is happening and need this issue to be fixed pretty quickly. Thanks!

Here’s the code for the screen (everything works perfectly so the other screens passing in data are not included):

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import 'package:flutter/material.dart';
import 'package:workout_app/Screens/Components/Sign_Up_Screens/screen2.dart';

class SingleSelectListViewWithLogo extends StatefulWidget {
  final List<String> items;
  const SingleSelectListViewWithLogo({Key? key, required this.items}) : super(key: key);
  @override
  _SingleSelectListViewWithLogoState createState() =>
      _SingleSelectListViewWithLogoState();
}

class _SingleSelectListViewWithLogoState extends State<SingleSelectListViewWithLogo> {
  int? selectedIndex;

  void returnScreen(context) {
    print('returning');
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(
        fullscreenDialog: true,
        builder: (context) => screen2(),
      ),
    );
  }

  bool nextValid = false;

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Material(
      child: Container (
        decoration: const BoxDecoration(color: Colors.grey),
        height: size.height,
        width: double.infinity,
        child: Stack(
          children: <Widget> [
            Positioned(
              top: size.height * .06,
              left: size.width * .03,
              child: InkWell(
                onTap: () {
                  returnScreen(context);
                },
                child: Image.asset(
                  alignment: Alignment.topLeft,
                  "assets/images/back2.png",
                  width: size.width * .07,
                ),
              ),
            ),
            Positioned(
              top: size.height * .09,
              left: size.width * .4,
              child: const Text(
                style: TextStyle(fontSize: 30, color: Color.fromARGB(255, 4, 3, 3)),
                'Goals'
              )
            ),
            Positioned(
              top: size.height * .15,
              left: size.width * .07,
              child: const Text(
                style: TextStyle(fontSize: 20, color: Color.fromARGB(255, 49, 48, 48)),
                'What body type do you want to get?'
              )
            ),
            Positioned(
              top: size.height * .26,
              left: size.width * .4,
              child: const Text(
                style: TextStyle(fontSize: 15, color: Color.fromARGB(255, 33, 31, 31)),
                'Select 1'
              )
            ),
            ListView.builder(
              itemCount: widget.items.length,
              itemBuilder: (context, index) {
                return GestureDetector(
                  onTap: () {
                    setState(() {
                      selectedIndex = index;
                      nextValid = true;
                    });
                  },
                  child: Container(
                    height: size.height * .15,
                    decoration: BoxDecoration(
                      color: selectedIndex == index ? Color.fromARGB(255, 40, 188, 72) : Color.fromARGB(255, 202, 195, 195),
                      border: Border.all(
                        color: selectedIndex == index ? Color.fromARGB(255, 16, 66, 37) : Colors.transparent,
                        width: 3,
                      ),
                      borderRadius: BorderRadius.circular(10),
                    ),
                    padding: const EdgeInsets.symmetric(horizontal: 10),
                    margin: EdgeInsets.fromLTRB(16, index == 0 ? MediaQuery.of(context).size.height * 0.265 : 0, 16, 8),
                    child: Row(
                      children: [
                        Flexible(
                          child: Text(widget.items[index]),
                        )
                      ],
                    ),
                  ),
                );
              },
            ),
            Positioned(
              top: size.height * .86,
              left: size.width * .1,
              child: SizedBox(
                width: size.width * .8,
                height: size.height * .08,
                child: ElevatedButton(
                  style: ButtonStyle(                  
                    backgroundColor: MaterialStateProperty.all<Color>(!nextValid ? Color.fromRGBO(69, 75, 85, 1) : Color.fromARGB(255, 0, 147, 246)),
                  ),
                  child: const Text('Continue',
                    style: TextStyle(fontSize: 20),
                  ),
                  onPressed: () async {
                  },
                ),
              ),
            ),
          ]
        )
      )
    );
  }
}

Thanks!

>Solution :

The problem here is that you’re using Stack widget everywhere, even when you’re rendering the ListView.builder. When this is the case, the ListView.builder covers the whole screen, especially when not given a bounded height/width. In that case since everything is in a Stack, based on how you write the widgets inside it, some of them stay on top while others will stay on the bottom, therefore not tappable. If I were to rewrite this implementation I would go with a Column and it would be like the following:

 @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Material(
        child: SafeArea(
      child: Container(
          decoration: const BoxDecoration(color: Colors.grey),
          height: size.height,
          width: double.infinity,
          child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                InkWell(
                  onTap: returnScreen,
                  child: const Icon(Icons.back_hand),
                ),
                const Text(
                    style: TextStyle(
                        fontSize: 30, color: Color.fromARGB(255, 4, 3, 3)),
                    'Goals'),
                const Text(
                    style: TextStyle(
                        fontSize: 20, color: Color.fromARGB(255, 49, 48, 48)),
                    'What body type do you want to get?'),
                const Text(
                    style: TextStyle(
                        fontSize: 15, color: Color.fromARGB(255, 33, 31, 31)),
                    'Select 1'),
                Expanded(
                  child: ListView.builder(
                    itemCount: widget.items.length,
                    itemBuilder: (context, index) {
                      return GestureDetector(
                        onTap: () {
                          setState(() {
                            selectedIndex = index;
                            nextValid = true;
                          });
                        },
                        child: Container(
                          height: size.height * .15,
                          decoration: BoxDecoration(
                            color: selectedIndex == index
                                ? const Color.fromARGB(255, 40, 188, 72)
                                : const Color.fromARGB(255, 202, 195, 195),
                            border: Border.all(
                              color: selectedIndex == index
                                  ? const Color.fromARGB(255, 16, 66, 37)
                                  : Colors.transparent,
                              width: 3,
                            ),
                            borderRadius: BorderRadius.circular(10),
                          ),
                          padding: const EdgeInsets.symmetric(horizontal: 10),
                          margin: EdgeInsets.fromLTRB(
                              16,
                              index == 0
                                  ? MediaQuery.of(context).size.height * 0.265
                                  : 0,
                              16,
                              8),
                          child: Row(
                            children: [
                              Flexible(
                                child: Text(widget.items[index]),
                              )
                            ],
                          ),
                        ),
                      );
                    },
                  ),
                ),
                Positioned(
                  top: size.height * .86,
                  left: size.width * .1,
                  child: SizedBox(
                    width: size.width * .8,
                    height: size.height * .08,
                    child: ElevatedButton(
                      style: ButtonStyle(
                        backgroundColor: MaterialStateProperty.all<Color>(
                            !nextValid
                                ? const Color.fromRGBO(69, 75, 85, 1)
                                : const Color.fromARGB(255, 0, 147, 246)),
                      ),
                      child: const Text(
                        'Continue',
                        style: TextStyle(fontSize: 20),
                      ),
                      onPressed: () async {},
                    ),
                  ),
                ),
              ])),
    ));
  }

But if you’re adamant in using a Stack instead of Column this is how you should go with it:

@override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Material(
      child: Container(
        decoration: const BoxDecoration(color: Colors.grey),
        height: size.height,
        width: double.infinity,
        child: Stack(
          children: <Widget>[
            Positioned(
                top: size.height * .09,
                left: size.width * .4,
                child: const Text(
                    style: TextStyle(
                        fontSize: 30, color: Color.fromARGB(255, 4, 3, 3)),
                    'Goals')),
            Positioned(
                top: size.height * .15,
                left: size.width * .07,
                child: const Text(
                    style: TextStyle(
                        fontSize: 20, color: Color.fromARGB(255, 49, 48, 48)),
                    'What body type do you want to get?')),
            Positioned(
                top: size.height * .26,
                left: size.width * .4,
                child: const Text(
                    style: TextStyle(
                        fontSize: 15, color: Color.fromARGB(255, 33, 31, 31)),
                    'Select 1')),
            ListView.builder(
              itemCount: widget.items.length,
              itemBuilder: (context, index) {
                return GestureDetector(
                  onTap: () {
                    setState(() {
                      selectedIndex = index;
                      nextValid = true;
                    });
                  },
                  child: Container(
                    height: size.height * .15,
                    decoration: BoxDecoration(
                      color: selectedIndex == index
                          ? const Color.fromARGB(255, 40, 188, 72)
                          : const Color.fromARGB(255, 202, 195, 195),
                      border: Border.all(
                        color: selectedIndex == index
                            ? const Color.fromARGB(255, 16, 66, 37)
                            : Colors.transparent,
                        width: 3,
                      ),
                      borderRadius: BorderRadius.circular(10),
                    ),
                    padding: const EdgeInsets.symmetric(horizontal: 10),
                    margin: EdgeInsets.fromLTRB(
                        16,
                        index == 0
                            ? MediaQuery.of(context).size.height * 0.265
                            : 0,
                        16,
                        8),
                    child: Row(
                      children: [
                        Flexible(
                          child: Text(widget.items[index]),
                        )
                      ],
                    ),
                  ),
                );
              },
            ),
            Positioned(
              top: size.height * .86,
              left: size.width * .1,
              child: SizedBox(
                width: size.width * .8,
                height: size.height * .08,
                child: ElevatedButton(
                  style: ButtonStyle(
                    backgroundColor: MaterialStateProperty.all<Color>(!nextValid
                        ? const Color.fromRGBO(69, 75, 85, 1)
                        : const Color.fromARGB(255, 0, 147, 246)),
                  ),
                  child: const Text(
                    'Continue',
                    style: TextStyle(fontSize: 20),
                  ),
                  onPressed: () async {},
                ),
              ),
            ),
            Positioned(
              top: size.height * .06,
              left: size.width * .03,
              child: InkWell(
                onTap: () {
                  returnScreen(context);
                },
                child: Image.asset(
                  alignment: Alignment.topLeft,
                  "assets/images/back2.png",
                  width: size.width * .07,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

Notice how I put the InkWell as the last child of the Stack, so it stays at the top and becomes tappable.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading