-1

i have this class :

class BottomNavBar extends StatefulWidget {
  final int activeTabIndex;

  const BottomNavBar({Key? key, required this.activeTabIndex})
      : super(key: key);

  @override
  BottomNavBarState createState() => BottomNavBarState();
}

class BottomNavBarState extends State<BottomNavBar> {
    static bool isCollapsed = false;
 @override
  Widget build(BuildContext context) {
 Scaffold(
        body: SlidingUpPanel(
          controller: _pc,
          panelBuilder: (sc) {
               setState(() {
          isCollapsed ? _pc.show(): _pc.hide();
        });
            return Container(
              child: Center(child: Text("Panel")),
            );
          },
          body: Text("something");
        ),  }
}

and I want to change value of variable isCollapsed in this class:

class _PlayerPreviewState extends State<PlayerPreview> {
  @override
  Widget build(BuildContext context) {
    final String play = 'assets/icons/play.svg';
    var pageWidth = MediaQuery.of(context).size.width;
    return  Padding(
        padding: EdgeInsets.only(top: pageWidth * .04),
        child: IconButton(
        onPressed: () {
        
             BottomNavBarState.isCollapsed = true;
                                   
         },
          icon: SvgPicture.asset(play),
                            ),
                          );}}

I want to when clicking on IconButton, isCollapsed is change to true.

and when I've print BottomNavBarState.isCollapsed , print true and its change. but in BottomNavBarState not change . and this part -> if (isCollapsed == true) _pc.show(); not work.

I know I should do it with the statement manager, but I don't know about them. so can anyone help me please? how can I change isCollaps and run _pc.show()

  • Why is `isCollapsed` `static`? – trojanfoe Oct 17 '21 at 18:04
  • I am learning Flutter myself and it doesn't feel right to me that you are calling methods on `_pc` from within `panelBuilder` closure. Instead I expect you are better off using a factory method of `_pc` (whatever it is) like this: `controller: isCollapsed ? PCThing.hidden() : PCThing.shown(),`. The idea being you return an object in a static state for the current state of the widget. – trojanfoe Oct 17 '21 at 18:10
  • As explained by [a comment to your other question](https://stackoverflow.com/questions/69604430/flutter-cant-access-static-variable#comment123030011_69604525), you need to call `setState` to trigger your `Widget` to be rebuilt with the updated value. – jamesdlin Oct 17 '21 at 18:13
  • I use static because I want to use it in another class. @trojanfoe –  Oct 17 '21 at 18:22
  • ok, where I should use `setState` in the code? @jamesdlin –  Oct 17 '21 at 18:23
  • You need to call `setState` on the widget that you want to be rebuilt, which would be the `BottomNavBar`. – jamesdlin Oct 17 '21 at 18:46
  • @jamesdlin I've edited my code. would you please see it? because still does not work. –  Oct 17 '21 at 19:00
  • No, you need to call `setState` on the `BottomNavBar` when you change `isCollapsed`. Since you apparently need `isCollapsed` to be `static` because you don't have a reference to the `BottomNavBar` instance, you also will not be able to call `setState` on the object. You should rethink your design to avoid the need for a `static` member. If you must, you could make the `BottomNavBar` object itself `static` instead. – jamesdlin Oct 17 '21 at 19:14
  • @jamesdlin I don't understand. would you please show it in my code? –  Oct 17 '21 at 20:41

2 Answers2

0

You shoudln't do this: BottomNavBarState.isCollapsed = true; Because you are changing the state from outside the state object, thus you are not referencing the same instance. Also you shouldn't be putting this variable as static.

Solution:

Is to create a function in a parent class of both the bottomBar that toggles the isCollapsed variable, for example:

Parent Widget

class ParentClass extends StatefulWidget {
  final int activeTabIndex;

  const ParentClass({Key? key, required this.activeTabIndex})
      : super(key: key);

  @override
  ParentClassState createState() => ParentClassState();
}

class ParentClassState extends State<ParentClass> {
    
  bool isCollapsed = false;

  void setCollapsed(bool collapsed) {
    setState(() {
      isCollapsed = collapsed;
    });
  }

 @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Player(
          setCollapsed: setCollapsed,
        ),
        BottomBar(
          isCollapsed: isCollapsed,
        ),
      ]
    );
  }
}

BottomBar:

class BottomNavBar extends StatefulWidget {
  final int activeTabIndex;
  final bool isCollapsed;

  const BottomNavBar({Key? key, required this.activeTabIndex, required this.isCollapsed})
      : super(key: key);

  @override
  BottomNavBarState createState() => BottomNavBarState();
}

class BottomNavBarState extends State<BottomNavBar> {
    

 @override
  Widget build(BuildContext context) {
 Scaffold(
        body: SlidingUpPanel(
          controller: _pc,
          panelBuilder: (sc) {
              widget.isCollapsed ? _pc.show(): _pc.hide();
            return Container(
              child: Center(child: Text("Panel")),
            );
          },
          body: Text("something");
        ),  }
}

Player:

class _PlayerPreviewState extends State<PlayerPreview> {
  @override
  Widget build(BuildContext context) {
    final String play = 'assets/icons/play.svg';
    var pageWidth = MediaQuery.of(context).size.width;
    return  Padding(
        padding: EdgeInsets.only(top: pageWidth * .04),
        child: IconButton(
          onPressed: () {
            widget.setCollapsed(true);
          },
          icon: SvgPicture.asset(play),
        ),
    );
  }
}
Mohammad Kurjieh
  • 1,043
  • 7
  • 16
-1

You can wrap the code with setState() where the app needs to check the changes and rebuild. therefore:

setState() {
  BottomNavBarState.isCollapsed  = true;
}

And I think it's better to use 'bool' instead of 'var' as the type is obvious for the variable 'isCollapsed'.