Search code examples
flutterdartvisibility

How to Hide a Button with a Visibility widget


Few Informations about me: Im 17y/o and from Germany. I have made a ListView to show Multiple Headers. Each Header should be a able to store multiple Subheaders which can be opened or closed. It should look like the toggle Function in the App Notion That is my first project.

I came up with two problems im not able to solve:

  1. When I close the Header 1, the Subheader1 is not visible, but the button can clicked and the spacce between Header 1 and 2 is two big. If Subheader 1 is not a TextButton it closes as expected.

  2. When I close Header 1 all Subheaders under that should close aswell. If someone can show me how it is done on the first Header and its Subheaders I can do the rest on my own

My code is: 



import 'package:flutter/material.dart';

class JWMGvereinfacht extends StatefulWidget {
  const JWMGvereinfacht({
    Key? key,
  }) : super(key: key);

  @override
  State<JWMGvereinfacht> createState() => _JWMGvereinfachtState();
}

class _JWMGvereinfachtState extends State<JWMGvereinfacht> {
  bool _isAnwendungsbereichVisible = false;
  bool _is1AnwendungsbereichVisible = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[900],
      body: Scrollbar(
        child: ListView(
          children: [
            Container(
              color: Colors.grey[850],
              width: double.infinity,
              height: 76,
              child: Padding(
                padding: const EdgeInsets.fromLTRB(8, 0, 0, 0),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: [
                        IconButton(
                          icon: const Icon(
                            Icons.arrow_back_ios_new,
                            color: Colors.white,
                            size: 25,
                          ),
                          onPressed: () {
                            Navigator.pop(context);
                          },
                        ),
                        const Expanded(
                          child: Padding(
                            padding: EdgeInsets.all(8.0),
                            child: Text(
                              "Titel",
                              style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 25,
                                  fontWeight: FontWeight.bold),
                              textAlign: TextAlign.end,
                            ),
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            ),
            Container(
              height: 5,
              color: Colors.grey[900],
            ),
            TextButton(
              onPressed: () {
                setState(() {
                  _isAnwendungsbereichVisible = !_isAnwendungsbereichVisible;
                });
              },
              child: Container(
                color: Colors.grey[850],
                width: double.infinity,
                height: 35,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: [
                    Icon(
                      _isAnwendungsbereichVisible
                          ? Icons.arrow_drop_down_outlined
                          : Icons.arrow_right,
                      color: Colors.white,
                    ),
                    const Expanded(
                      child: Padding(
                        padding: EdgeInsets.all(8.0),
                        child: Text(
                          "Header 1",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 17,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.fromLTRB(17.5, 0, 8, 0),
              child: TextButton(
                onPressed: () {
                  setState(() {
                    _is1AnwendungsbereichVisible =
                        !_is1AnwendungsbereichVisible;
                  });
                },
                child: Visibility(
                  visible: _isAnwendungsbereichVisible,
                  child: Column(
                    children: [
                      Container(
                        color: Colors.blue,
                        width: double.infinity,
                        height: 35,
                        child: const Padding(
                          padding: EdgeInsets.all(8.0),
                          child: Text(
                            "Subheader 1",
                            style: TextStyle(
                              color: Colors.white,
                              fontSize: 15.5,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.fromLTRB(35, 0, 0, 8),
              child: Visibility(
                visible: _is1AnwendungsbereichVisible,
                child: Column(
                  children: [
                    TextButton(
                      onPressed: () {},
                      child: Container(
                        color: Colors.blue,
                        width: double.infinity,
                        height: 35,
                        child: const Padding(
                          padding: EdgeInsets.all(8.0),
                          child: Text(
                            "Inhalt",
                            style: TextStyle(
                              color: Colors.white,
                              fontSize: 15.5,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Container(
                color: Colors.grey[850],
                width: double.infinity,
                height: 35,
                child: const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text("Header 2",
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 17,
                        fontWeight: FontWeight.bold,
                      )),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Container(
                color: Colors.grey[850],
                width: double.infinity,
                height: 35,
                child: const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text("Beteiligung Dritter an der Jagd (§17-§25)",
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 17,
                        fontWeight: FontWeight.bold,
                      )),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Container(
                color: Colors.grey[850],
                width: double.infinity,
                height: 35,
                child: const Padding(
                  padding: EdgeInsets.all(7.0),
                  child: Text("Jagdschein (§26-§28)",
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 17,
                        fontWeight: FontWeight.bold,
                      )),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Container(
                color: Colors.grey[850],
                width: double.infinity,
                height: 57,
                child: const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text(
                      "Besondere Rechte und Pflichten bei der Jagdausübung (§29-§40)",
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 17,
                        fontWeight: FontWeight.bold,
                      )),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Container(
                color: Colors.grey[850],
                width: double.infinity,
                height: 35,
                child: const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text(
                      "Sicherung der Nachhaltigkeit, Wildtierschutz (§41-§51)",
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 17,
                        fontWeight: FontWeight.bold,
                      )),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Container(
                color: Colors.grey[850],
                width: double.infinity,
                height: 35,
                child: const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text("Wild- und Jagdschaden (§51a-§57)",
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 17,
                        fontWeight: FontWeight.bold,
                      )),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Container(
                color: Colors.grey[850],
                width: double.infinity,
                height: 35,
                child: const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text("Verwaltungsbehörden, Beiräte (§58-§65)",
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 17,
                        fontWeight: FontWeight.bold,
                      )),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Container(
                color: Colors.grey[850],
                width: double.infinity,
                height: 35,
                child: const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text("Straf- und Bußgeldvorschriften (§66-§69)",
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 17,
                        fontWeight: FontWeight.bold,
                      )),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

I tried wrapping the whole Subheader 1 within a own Container but nothing changed, I want that all Subheaders are closed, when the Header 1 is closed and the Space between the Headers should be 8.0


Solution

  • You can set the _is1AnwendungsbereichVisible = false; when _isAnwendungsbereichVisible is false.

    TextButton(
      onPressed: () {
        _isAnwendungsbereichVisible = !_isAnwendungsbereichVisible;
        if (_isAnwendungsbereichVisible == false) {
          _is1AnwendungsbereichVisible = false;
        }
        setState(() {});
      },
      child: Container(
        color: Colors.grey[850],
        width: double.infinity,
        height: 35,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Icon(
              _isAnwendungsbereichVisible
                  ? Icons.arrow_drop_down_outlined
                  : Icons.arrow_right,
              color: Colors.white,
            ),
            const Expanded(
              child: Padding(
                padding: EdgeInsets.all(8.0),
                child: Text(
                  "Header 1",
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 17,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    ),
    

    Full snippet

    class JWMGvereinfacht extends StatefulWidget {
      const JWMGvereinfacht({
        Key? key,
      }) : super(key: key);
    
      @override
      State<JWMGvereinfacht> createState() => _JWMGvereinfachtState();
    }
    
    class _JWMGvereinfachtState extends State<JWMGvereinfacht> {
      bool _isAnwendungsbereichVisible = false;
      bool _is1AnwendungsbereichVisible = false;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.grey[900],
          body: Scrollbar(
            child: ListView(
              children: [
                Container(
                  color: Colors.grey[850],
                  width: double.infinity,
                  height: 76,
                  child: Padding(
                    padding: const EdgeInsets.fromLTRB(8, 0, 0, 0),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Row(
                          mainAxisAlignment: MainAxisAlignment.start,
                          children: [
                            IconButton(
                              icon: const Icon(
                                Icons.arrow_back_ios_new,
                                color: Colors.white,
                                size: 25,
                              ),
                              onPressed: () {
                                Navigator.pop(context);
                              },
                            ),
                            const Expanded(
                              child: Padding(
                                padding: EdgeInsets.all(8.0),
                                child: Text(
                                  "Titel",
                                  style: TextStyle(
                                      color: Colors.white,
                                      fontSize: 25,
                                      fontWeight: FontWeight.bold),
                                  textAlign: TextAlign.end,
                                ),
                              ),
                            ),
                          ],
                        ),
                      ],
                    ),
                  ),
                ),
                Container(
                  height: 5,
                  color: Colors.grey[900],
                ),
                TextButton(
                  onPressed: () {
                    _isAnwendungsbereichVisible = !_isAnwendungsbereichVisible;
                    if (_isAnwendungsbereichVisible == false) {
                      _is1AnwendungsbereichVisible = false;
                    }
                    setState(() {});
                  },
                  child: Container(
                    color: Colors.grey[850],
                    width: double.infinity,
                    height: 35,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: [
                        Icon(
                          _isAnwendungsbereichVisible
                              ? Icons.arrow_drop_down_outlined
                              : Icons.arrow_right,
                          color: Colors.white,
                        ),
                        const Expanded(
                          child: Padding(
                            padding: EdgeInsets.all(8.0),
                            child: Text(
                              "Header 1",
                              style: TextStyle(
                                color: Colors.white,
                                fontSize: 17,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(17.5, 0, 8, 0),
                  child: TextButton(
                    onPressed: () {
                      setState(() {
                        _is1AnwendungsbereichVisible =
                            !_is1AnwendungsbereichVisible;
                      });
                    },
                    child: Visibility(
                      visible: _isAnwendungsbereichVisible,
                      child: Column(
                        children: [
                          Container(
                            color: Colors.blue,
                            width: double.infinity,
                            height: 35,
                            child: const Padding(
                              padding: EdgeInsets.all(8.0),
                              child: Text(
                                "Subheader 1",
                                style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 15.5,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(35, 0, 0, 8),
                  child: Visibility(
                    visible: _is1AnwendungsbereichVisible,
                    child: Column(
                      children: [
                        TextButton(
                          onPressed: () {},
                          child: Container(
                            color: Colors.blue,
                            width: double.infinity,
                            height: 35,
                            child: const Padding(
                              padding: EdgeInsets.all(8.0),
                              child: Text(
                                "Inhalt",
                                style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 15.5,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Container(
                    color: Colors.grey[850],
                    width: double.infinity,
                    height: 35,
                    child: const Padding(
                      padding: EdgeInsets.all(8.0),
                      child: Text("Header 2",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 17,
                            fontWeight: FontWeight.bold,
                          )),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Container(
                    color: Colors.grey[850],
                    width: double.infinity,
                    height: 35,
                    child: const Padding(
                      padding: EdgeInsets.all(8.0),
                      child: Text("Beteiligung Dritter an der Jagd (§17-§25)",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 17,
                            fontWeight: FontWeight.bold,
                          )),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Container(
                    color: Colors.grey[850],
                    width: double.infinity,
                    height: 35,
                    child: const Padding(
                      padding: EdgeInsets.all(7.0),
                      child: Text("Jagdschein (§26-§28)",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 17,
                            fontWeight: FontWeight.bold,
                          )),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Container(
                    color: Colors.grey[850],
                    width: double.infinity,
                    height: 57,
                    child: const Padding(
                      padding: EdgeInsets.all(8.0),
                      child: Text(
                          "Besondere Rechte und Pflichten bei der Jagdausübung (§29-§40)",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 17,
                            fontWeight: FontWeight.bold,
                          )),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Container(
                    color: Colors.grey[850],
                    width: double.infinity,
                    height: 35,
                    child: const Padding(
                      padding: EdgeInsets.all(8.0),
                      child: Text(
                          "Sicherung der Nachhaltigkeit, Wildtierschutz (§41-§51)",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 17,
                            fontWeight: FontWeight.bold,
                          )),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Container(
                    color: Colors.grey[850],
                    width: double.infinity,
                    height: 35,
                    child: const Padding(
                      padding: EdgeInsets.all(8.0),
                      child: Text("Wild- und Jagdschaden (§51a-§57)",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 17,
                            fontWeight: FontWeight.bold,
                          )),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Container(
                    color: Colors.grey[850],
                    width: double.infinity,
                    height: 35,
                    child: const Padding(
                      padding: EdgeInsets.all(8.0),
                      child: Text("Verwaltungsbehörden, Beiräte (§58-§65)",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 17,
                            fontWeight: FontWeight.bold,
                          )),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Container(
                    color: Colors.grey[850],
                    width: double.infinity,
                    height: 35,
                    child: const Padding(
                      padding: EdgeInsets.all(8.0),
                      child: Text("Straf- und Bußgeldvorschriften (§66-§69)",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 17,
                            fontWeight: FontWeight.bold,
                          )),
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }