为啥当我在其小部件中调用 Flutter 有状态小部件时,它没有改变另一个有状态小部件的状态

Posted

技术标签:

【中文标题】为啥当我在其小部件中调用 Flutter 有状态小部件时,它没有改变另一个有状态小部件的状态【英文标题】:Why Flutter statefull widget didn't change the state of another statefull widget when I call it inside its widget为什么当我在其小部件中调用 Flutter 有状态小部件时,它没有改变另一个有状态小部件的状态 【发布时间】:2021-07-12 23:10:58 【问题描述】:

我创建了两个 Stateful Widget 类名称 Editor,其中包含员工卡 UI 和控制卡中项目半径的 RPMSlider()

我在Editor Widget 中调用RPMSlider(),如下图所示,

image

我的问题是,当我调整滑块时,它完美地工作并显示其上方的值。

但它不能同时在卡片 UI 中进行更改。直到我点击具有 SetState();

buttongesturedetector

Editor() 内部创建滑块功能时,它可以正常工作,但在单独的有状态小部件中,它不能在卡片中进行更改

这里是 Gif Show

这是一个编辑器

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(),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  

这是 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;
             );
            
           ,
         ),
       ],
     ),
   );




【问题讨论】:

那是 的代码。也许您可以将其分解为minimal reproducible example? 代码已被破坏,重现性极差,谢谢 您应该会看到 GIF 图像。查看实际问题。 【参考方案1】:

你是对的,滑块不能改变另一个小部件。它只能自己改变。它还可以在 更改时提供回调。其他小部件已经这样做了,例如您使用的 NeumorphicSlider 有一个 onChanged 回调,它会在发生更改时调用它,以便您可以在小部件之外进行调整。

所以也给你的小部件一个onChanged 回调:

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

  RPMSlider(this.onChanged); 

现在在您的状态类中,每当您收到值已更改的通知时,您都会通知其他人已更改:

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

现在在您的 EditorState 中,您可以像这样使用它:

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
     );
)

所以现在,setState 方法在正确的状态类中被调用,它实际上可以改变两个小部件,滑块和另一个。

【讨论】:

以上是关于为啥当我在其小部件中调用 Flutter 有状态小部件时,它没有改变另一个有状态小部件的状态的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:如何从浮动操作按钮调用小部件状态类的方法

如何从另一个 dart 文件中调用有状态小部件(有表单)方法?- Flutter

从另一个有状态小部件调用一个有状态小部件中的方法 - Flutter

Flutter 中的有状态和无状态小部件之间的关系是啥?

如何让内部有状态小部件接收到 Flutter 中的滚动事件?

Flutter/Dart:我的小部件树中可以有多个带有状态的小部件吗?