Why Flutter statefull widget didn't change the state of another statefull widget when I call it inside its widget

Issue

I have created two Stateful Widget classes name Editor{} that contains the Employee card UI and the RPMSlider() that controls the Radius of Items in a card.

I call the RPMSlider() in Editor Widget which looks like this in the below image,

image

My question is when I Adjust the slider it perfectly works and shows the value above it.

But it cannot make a change in the meantime in a Card UI. Until I click a button or gesturedetector having SetState();

Slider function works fine when it is created inside Editor() but in a separate Stateful widget it cannot make changes in Card

Here is The
Gif Show

This is an Editor

class Editor extends StatefulWidget {
  @override
  _EditorState createState() => _EditorState();
}
class _EditorState extends State<Editor> {
  double size = 1;
  var width, height;
  @override
  Widget build(BuildContext context) {
    width = MediaQuery.of(context).size.width;
    height = MediaQuery.of(context).size.height;
    // print(width* 0.5733);
    return SafeArea(
      child: Container(
        width: MediaQuery.of(context).size.width,
        child: Row(
          children: [
            //TODO: Left Side
            Container(
              width: width * 0.300,
              color: Color(0xffdbe5e7),
              child: Column(
                children: [
                  //Permanent Area
                ],
              ),
            ),

            Container(
              height: height,
              padding: EdgeInsets.only(top: 10),
              width: width * 0.400,
              decoration: BoxDecoration(
                color: Color(0xffdbe5e7),
              ),
              //TODO: Card Area

              child: FlipCard(
                key: cardKey,
                flipOnTouch: false,
                ///EDITABLE CARD FRONT
                front: Container(),
                ///EDITABLE CARD Back
                back: Container(),
              ),
            ),
            Container(
              width: width * 0.300,
              color: Color(0xffdbe5e7),
              child: Column(
                children: [
                  //TODO: Radius , Padding , Margins
                  RPMSlider(),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

This is RPMSlider

 class RPMSlider extends StatefulWidget {


  @override
  _RPMSliderState createState() => _RPMSliderState();

}

class _RPMSliderState extends State<RPMSlider> {

  @override
  Widget build(BuildContext context) {

    return radius(caseId: widgetIdCarrier,);

  }

 radius({required String caseId,label='label',position='topLeft'}) {
   return Padding(
     padding: const EdgeInsets.all(4.0),
     child: Column(
       children: [
         Row(
           children: [
             Text(
               label.toUpperCase(),
               style: TextStyle(fontSize: 10, color: Colors.black54),
             ),
             Spacer(),
             Text(
               radiusValue.round().toString(),
               style: TextStyle(fontSize: 10, color: Colors.black54),
             ),
           ],
         ),
         SizedBox(
           height: 4,
         ),
         NeumorphicSlider(
           min: 0.0,
           max: 30,
           sliderHeight: 30,
           thumb: NeumorphicIcon(
             Icons.circle,
             size: 20,
           ),
           height: 1,
           style: SliderStyle(
               borderRadius: BorderRadius.circular(3),
               lightSource: LightSource.bottomRight),
           value:radiusValue

           onChanged: (sts) {
             setState(() {
               radiusValue=sts;
             });
            
           },
         ),
       ],
     ),
   );
}


}

Solution

You are right, the slider cannot change another widget. It can only change it self. It can also provide callbacks when it has changed. Other widgets already do that, like the NeumorphicSlider that you use has an onChanged callback that it calls when something has changed so you can make adjustments outside the widget.

So give your widget an onChanged callback, too:

class RPMSlider extends StatefulWidget {
  final ValueChanged<int>? onChanged;

  RPMSlider({this.onChanged}); 

Now in your state class, whenever you get notified that the value has changed, you notify others that is has changed:

  onChanged: (sts) {
     setState(() {
       radiusValue = sts;
     });
     // the new part:
     final callBack = widget.onChanged
     if(callBack != null) {
        callBack(sts);
     }

Now in your EditorState, you can use it like this:

RPMSlider(onChanged: (value) {
     setState(() {
       your_state_variable = value; 
       // don't know what your_state_variable is,
       // you need to pick the one you need for this
     });
})

So now, the setState method is called inside the correct state class, that can actually change both widgets, the slider and the other one.

Answered By – nvoigt

Answer Checked By – Mildred Charles (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *