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

How to change (setState) of class from appBar or bottomNavigationBar?

I want to click a button at appBar or bottomNavigationBar (InkWell on tap) and based on my click to change what widget to be loaded at screen. Something like this example with appBar, 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 MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: MyAppBar(),
      body: MyContent(),
    );
  }
}

class MyAppBar extends StatelessWidget implements PreferredSizeWidget {
  const MyAppBar({
    super.key,
  });

  @override
  Size get preferredSize => const Size.fromHeight(50);

  @override
  Widget build(BuildContext context) {
    return AppBar(
      title: Row(
        children: [
          InkWell(
            onTap: () {
              // WHAT TO DO HERE ?
            },
            child: const Text('Text'),
          ),
          const SizedBox(width: 20),
          InkWell(
            onTap: () {
              // WHAT TO DO HERE ?
            },
            child: const Text('Image'),
          ),
        ],
      ),
    );
  }
}

class MyContent extends StatefulWidget {
  MyContent({
    super.key,
  });

  @override
  State<MyContent> createState() => _MyContentState();
}

class _MyContentState extends State<MyContent> {
  var myChoice = 0;

  // WHAT TO DO HERE ? ADD setState() ?

  @override
  Widget build(BuildContext context) {
    switch (myChoice) {
      case 1:
        return const Text('You clicked TEXT');
      case 2:
        return Image.network('https://picsum.photos/250');
    }
    return const Text('Waiting for action at App Bar...');
  }
}

I expect to load Text or Image widget based onTap at InkWell at appBar.

What to set at onTap (where "// WHAT TO DO HERE ?" is now)? Also I guess I need to add some code inside class too (where "// WHAT TO DO HERE ? ADD setState() ?" is).

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

"It looks like your post is mostly code; please add some more details." … Well, I have no idea what more to add. I wanted to post whole code, so it may be a bit longer, but better have it all, than few small pieces of code and not have idea where and what to do.

>Solution :

To change the widget displayed on the screen based on a tap in the AppBar, you need to pass a callback function from the parent widget (MyHomePage) to the child widget (MyAppBar). This callback function will update the state of MyHomePage, and then rebuild the widget tree, showing the appropriate widget based on the updated state.

Here’s an updated version of your code:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _myChoice = 0;

  void _updateChoice(int choice) {
    setState(() {
      _myChoice = choice;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: MyAppBar(onChoiceSelected: _updateChoice),
      body: MyContent(myChoice: _myChoice),
    );
  }
}

class MyAppBar extends StatelessWidget implements PreferredSizeWidget {
  const MyAppBar({Key? key, required this.onChoiceSelected})
      : super(key: key);

  final Function(int) onChoiceSelected;

  @override
  Size get preferredSize => const Size.fromHeight(50);

  @override
  Widget build(BuildContext context) {
    return AppBar(
      title: Row(
        children: [
          InkWell(
            onTap: () {
              onChoiceSelected(1);
            },
            child: const Text('Text'),
          ),
          const SizedBox(width: 20),
          InkWell(
            onTap: () {
              onChoiceSelected(2);
            },
            child: const Text('Image'),
          ),
        ],
      ),
    );
  }
}

class MyContent extends StatelessWidget {
  const MyContent({Key? key, required this.myChoice}) : super(key: key);

  final int myChoice;

  @override
  Widget build(BuildContext context) {
    switch (myChoice) {
      case 1:
        return const Center(child: Text('You clicked TEXT'));
      case 2:
        return const Center(child: Image.network('https://picsum.photos/250'));
      default:
        return const Center(child: Text('Waiting for action at App Bar...'));
    }
  }
}

In the updated code, MyHomePage has a state variable _myChoice that holds the current choice made by the user. _updateChoice is a function that takes an integer parameter choice and updates the state variable _myChoice with the new value.

MyAppBar has a callback function onChoiceSelected that is called when the user taps on the Text or Image InkWell widgets. The callback function passes the selected choice to the parent widget (MyHomePage) using _updateChoice.

MyContent has a required parameter myChoice that is passed from the parent widget (MyHomePage) to determine which widget to display.

With this implementation, tapping on the Text or Image InkWell widgets in the AppBar will trigger the callback function, which will update the state variable _myChoice. This will cause the widget tree to rebuild, showing the appropriate widget based on the updated _myChoice value.

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