How can I use an appBar icon to open and close a ListView?

30 Views Asked by At

I am trying to create an app with a UI similar to Simplenote's. In the screenshot below, when the screenwidth > some value, the UI displays a ListView on the left and TextField on the right.:

screenshot

If the icon on the left side of the TextField's appBar is clicked, the ListView closes:

enter image description here

How do I code this? I'm not asking about an app Drawer, I think. I've already coded that app so that with narrow screenwidths users are presented with the ListView, click an item, and then the TextField's view is pushed. And with wider screenwidths users are presented with the ListView and TextField both visible. I'd like users to be able to click the appBar icon (in a wider view) and dismiss the ListView.

1

There are 1 best solutions below

0
diegoveloper On BEST ANSWER

You can achieve this using callbacks, I prepared a sample for you.

Result

enter image description here

Code:

class NotesAppDemo extends StatefulWidget {
  const NotesAppDemo({super.key});

  @override
  State<NotesAppDemo> createState() => _NotesAppDemoState();
}

class _NotesAppDemoState extends State<NotesAppDemo> {
  bool showDetailsOnly = false;

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (context, constraints) {
      if (constraints.maxWidth > 300) {
        return Row(
          children: [
            if (!showDetailsOnly)
              Expanded(
                flex: 1,
                child: MenuView(onMenuClicked: () {
                  setState(() {
                    showDetailsOnly = true;
                  });
                }),
              ),
            Expanded(
              flex: 3,
              child: DetailsView(
                onMenuClicked: () {
                  setState(() {
                    showDetailsOnly = false;
                  });
                },
              ),
            ),
          ],
        );
      } else {
        return MenuView(
          onMenuClicked: () {
            //do any action for single view
          },
        );
      }
    });
  }
}

class MenuView extends StatelessWidget {
  const MenuView({
    required this.onMenuClicked,
    super.key,
  });

  final VoidCallback? onMenuClicked;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: const Icon(Icons.menu),
          onPressed: onMenuClicked,
        ),
        title: const Text('All Notes'),
      ),
      body: ListView(
        children: [
          ListTile(
            title: const Text('Notes'),
            onTap: () {
              print('Notes');
            },
          ),
          ListTile(
            title: const Text('Details'),
            onTap: () {
              print('Details');
            },
          ),
        ],
      ),
    );
  }
}

class DetailsView extends StatelessWidget {
  const DetailsView({
    required this.onMenuClicked,
    super.key,
  });

  final VoidCallback? onMenuClicked;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: const Icon(Icons.view_sidebar_sharp),
          onPressed: onMenuClicked,
        ),
      ),
      body: const Placeholder(),
    );
  }
}