skip to Main Content

Hello I try to refresh _currentValue when I open a modal bottom sheet and I change the value from state full widget depense().

Here is my code

new RaisedButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
elevation: 5,
highlightElevation: 10,
color: Colors.white,
splashColor: Colors.white,
    child :  new  Text("${_currentValue}",textAlign: TextAlign.center,  style: TextStyle(color: Colors.black, fontWeight: FontWeight.w400, fontSize:  SizeConfig.safeBlockHorizontal! * 4)),
        padding: const EdgeInsets.all (15.0),
        onPressed: () {
        setState(() {
        showMaterialModalBottomSheet(isDismissible: true,
        shape:  RoundedRectangleBorder(
        borderRadius:
        BorderRadius.circular(15)),
        context: context,
        builder: (context) => depense()
          );
          });
          }),

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

  @override
  State<depense> createState() => _depenseState();
}

class _depenseState extends State<depense> {

  int _currentValue = 5;
 
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return  Container(
        width: MediaQuery.of(context).size.width/1,
        height: MediaQuery.of(context).size.height/1.8,
        child :
        Padding(
            padding: const EdgeInsets.only(left:20,right:20),
            child:
          
              Container(
                alignment: Alignment.center,
                child: NumberPicker(
                  axis: Axis.horizontal,
                  itemHeight: 70,
                  itemWidth: 70,
                  step: 1,
                  selectedTextStyle: const TextStyle(
                    fontSize: 30.0,
                    color: Color(0xff61d3cb),
                    fontWeight: FontWeight.w800,
                  ),
                  textStyle: const TextStyle(
                    color: Colors.black,
                    fontSize: 12.0,
                  ),
                  value: _currentValue,
                  minValue: 0,
                  maxValue: 1000,

                  onChanged: (v) {
                    setState(() {
                      _currentValue = v;

                    });
                  },
                ),
              ),
             
            ));
  }
}

If I add the widget build from depense state full widget directly on the modalbottomsheet like bellow, Text("${_currentValue}" is upgrade but NumberPicker return to initial value…
But when I create the statefull widget I can use NumberPicker but not refresh data…

 new RaisedButton(

  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
  elevation: 5,
  highlightElevation: 10,
  color: Colors.white,
  splashColor: Colors.white,
  child :  new  Text("${_currentValue}",textAlign: TextAlign.center,  style: TextStyle(color: Colors.black, fontWeight: FontWeight.w400, fontSize:  SizeConfig.safeBlockHorizontal! * 4)),
  padding: const EdgeInsets.all (15.0),
  onPressed: () {


setState(() {
  showMaterialModalBottomSheet(isDismissible: true,
      shape:  RoundedRectangleBorder(
          borderRadius:
          BorderRadius.circular(15)),

      context: context,
      builder: (context) =>  Container(


          width: MediaQuery.of(context).size.width/1,
          height: MediaQuery.of(context).size.height/1.8,

          child :
          Padding(
              padding: const EdgeInsets.only(left:20,right:20),
              child:
           
                      Container(
                        alignment: Alignment.center,
                        child: NumberPicker(
                          axis: Axis.horizontal,
                          itemHeight: 70,
                          itemWidth: 70,
                          step: 1,
                          selectedTextStyle: const TextStyle(
                            fontSize: 30.0,
                            color: Color(0xff61d3cb),
                            fontWeight: FontWeight.w800,
                          ),
                          textStyle: const TextStyle(
                            color: Colors.black,
                            fontSize: 12.0,
                          ),
                          value: _currentValue,
                          minValue: 0,
                          maxValue: 1000,

                          onChanged: (v) {
                            setState(() {
                              _currentValue = v;

                            });
                          },
                        ),
                      ),
          ))
  );
});

                                      }),

2

Answers


  1. It looks like _currentValue is a local state variable of the dispense class and you have another variable by same name in parent class also. Changes in local state variables are not reflected in parent widgets.

    Usually, you should use any state management libraries in such scenarios, but a simple solution can be to pass a callback function from RaisedButton to dispense widget which will return its value.

    class depense extends StatefulWidget {
       Function changeCurrentValue(int val);
    
      const depense({Key? key}) : super(key: key);
    
      @override
      State<depense> createState() => _depenseState();
    }
    
    class _depenseState extends State<depense> {
       ...
    
        @override
      Widget build(BuildContext context) {
        return  Container(
            width: MediaQuery.of(context).size.width/1,
            height: MediaQuery.of(context).size.height/1.8,
            child :
            ...
            onChanged: (v) {
               widget.changeCurrentValue(v);
           }
    

    In RaisedButton

    int _currentValue = 5;
    
    void changeCurrentValue(int v){
       setState(() {
           _currentValue = v;
        })
    }
    
    new RaisedButton(
       ...
       showMaterialModalBottomSheet(isDismissible: true,
            shape:  RoundedRectangleBorder(
            borderRadius:
            BorderRadius.circular(15)),
            context: context,
            builder: (context) => depense(changeCurrentValue: changeCurrentValue)
        ....
    
       
    
    
       
    
    Login or Signup to reply.
  2. You need define currentValue in your main class and pass a function to depense class like this:

    class depense extends StatefulWidget {
      final Function(int) onChange; //<-- add this
      const depense({Key? key, required this.onChange}) : super(key: key);
    
      @override
      State<depense> createState() => _depenseState();
    }
    
    class _depenseState extends State<depense> {
      int _currentValue = 5;
      @override
      Widget build(BuildContext context) {
        return Container(
            width: MediaQuery.of(context).size.width / 1,
            height: MediaQuery.of(context).size.height / 1.8,
            child: Padding(
              padding: const EdgeInsets.only(left: 20, right: 20),
              child: Container(
                alignment: Alignment.center,
                child: NumberPicker(
                  axis: Axis.horizontal,
                  itemHeight: 70,
                  itemWidth: 70,
                  step: 1,
                  selectedTextStyle: const TextStyle(
                    fontSize: 30.0,
                    color: Color(0xff61d3cb),
                    fontWeight: FontWeight.w800,
                  ),
                  textStyle: const TextStyle(
                    color: Colors.black,
                    fontSize: 12.0,
                  ),
                  value: _currentValue,
                  minValue: 0,
                  maxValue: 1000,
                  onChanged: (v) {
                    widget.onChange(v);
                    setState(() {
                      _currentValue = v;
                    });
                  },
                ),
              ),
            ));
      }
    }
    

    Then you use it like this:

     RaisedButton(
          shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(10)),
          elevation: 5,
          highlightElevation: 10,
          color: Colors.white,
          splashColor: Colors.white,
          child: new Text("${_currentValue}",
              textAlign: TextAlign.center,
              style: TextStyle(
                  color: Colors.black,
                  fontWeight: FontWeight.w400,
                  fontSize: SizeConfig.safeBlockHorizontal! * 4)),
          padding: const EdgeInsets.all(15.0),
          onPressed: () {
            setState(() {
              showMaterialModalBottomSheet(
                  isDismissible: true,
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(15)),
                  context: context,
                  builder: (context) => depense(onChange:(value){
                     setState(() {
                         _currentValue = value;
                     });
                  }));
            });
          })
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search