从另一个小部件控制一个小部件的状态
Controlling state of a widget from another widget
我在此 link 中使用示例:
https://medium.com/@jb.padamchopra/implementing-a-bottom-app-bar-with-floating-action-button-flutter-463560e1324
Widget from the link
浮动动作按钮动画由bool clickedCenterFAB控制
在我的代码中,动画容器内的小部件在 class 中定义,我希望在用户编写文本并按下按钮后,动画容器折叠,所以逻辑上我想调用 setState 并分配 clickedCenterFAB =错误的。
我是 flutter 的新手,我尝试在 uploadPage 小部件内调用 setState 并尝试更改 clickedCenterFAB 但它没有用。知道怎么做吗?我在这里先向您的帮助表示感谢。
My widget
AnimatedContainer(
duration: Duration(milliseconds: 300),
//if clickedCentreFAB == true, the first parameter is used. If it's false, the second.
height: clickedCentreFAB
? MediaQuery.of(context).size.height
: 10.0,
width: clickedCentreFAB
? MediaQuery.of(context).size.height
: 10.0,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(clickedCentreFAB ? 0.0 : 300.0),
color: Colors.blue,
),
child: clickedCentreFAB ? UploadPage() : null)
编辑:在遵循迈克尔的解决方案并跟上评论之后,这就是我得到的地方
class UploadPage extends StatefulWidget {
final Function collapseContainer;
UploadPage(this.collapseContainer);
@override
_UploadPageState createState() =>
_UploadPageState(collapseContainer);
}
class _UploadPageState extends State<UploadPage> {
final Function collapseContainer;
_UploadPageState(this.collapseContainer);
...
...
CustomButton(
() {
if (_controller.text.trim().isNotEmpty) {
DatabaseServices().uploadPost(
FirebaseAuth.instance.currentUser.uid,
_controller.text,
!_isChecked);
collapseContainer;
}
},
'Post',
Colors.white,
),
CustomButton 显然是我创建的一个小部件 class 以避免冗余,并且在我传递到这里的函数的参数中
您不能直接从 UploadPage 调用 setState 的原因是因为 setState 是一个 class 方法,所以它总是只与直接封闭的 class 实例的状态相关联。如果你想改变 Widget 树中更高层的 Widget 的状态,标准方法是将回调传递给子组件。
在您的情况下,您可以向 UploadPage 小部件添加一个新的 属性 - 例如 onButtonPressed:
class UploadPage extends StatelessWidget {
final Function onButtonPressed;
UploadPage({required this.onButtonPressed});
@override
Widget build(BuildContext context) {
return YourWidget(
// ...
child: RaisedButton(onPressed: onButtonPressed),
// ...
);
}
}
然后:
AnimatedContainer(
// ...
child: clickedCentreFAB
? UploadPage(
onButtonPressed: () {
setState(() { return clickedCentreFAB = false; });
},
)
: null,
)
)
顺便说一句,在某个时刻,您的应用程序的状态可能非常复杂,足以保证像 bloc
、redux
等解决方案 - 但是,对于这种特定情况,这些可能是矫枉过正。
如果您发现自己必须通过小部件树的多个级别传递回调和属性,那么 provider
会非常有用。
如果动作、状态和视图之间的映射变得非常复杂,那么 bloc
或 redux
可以帮助将结构强加到您的项目中并使其更容易推理,尽管您会通常需要编写更多代码才能完成相同的任务。
我在此 link 中使用示例: https://medium.com/@jb.padamchopra/implementing-a-bottom-app-bar-with-floating-action-button-flutter-463560e1324 Widget from the link
浮动动作按钮动画由bool clickedCenterFAB控制 在我的代码中,动画容器内的小部件在 class 中定义,我希望在用户编写文本并按下按钮后,动画容器折叠,所以逻辑上我想调用 setState 并分配 clickedCenterFAB =错误的。 我是 flutter 的新手,我尝试在 uploadPage 小部件内调用 setState 并尝试更改 clickedCenterFAB 但它没有用。知道怎么做吗?我在这里先向您的帮助表示感谢。 My widget
AnimatedContainer(
duration: Duration(milliseconds: 300),
//if clickedCentreFAB == true, the first parameter is used. If it's false, the second.
height: clickedCentreFAB
? MediaQuery.of(context).size.height
: 10.0,
width: clickedCentreFAB
? MediaQuery.of(context).size.height
: 10.0,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(clickedCentreFAB ? 0.0 : 300.0),
color: Colors.blue,
),
child: clickedCentreFAB ? UploadPage() : null)
编辑:在遵循迈克尔的解决方案并跟上评论之后,这就是我得到的地方
class UploadPage extends StatefulWidget {
final Function collapseContainer;
UploadPage(this.collapseContainer);
@override
_UploadPageState createState() =>
_UploadPageState(collapseContainer);
}
class _UploadPageState extends State<UploadPage> {
final Function collapseContainer;
_UploadPageState(this.collapseContainer);
...
...
CustomButton(
() {
if (_controller.text.trim().isNotEmpty) {
DatabaseServices().uploadPost(
FirebaseAuth.instance.currentUser.uid,
_controller.text,
!_isChecked);
collapseContainer;
}
},
'Post',
Colors.white,
),
CustomButton 显然是我创建的一个小部件 class 以避免冗余,并且在我传递到这里的函数的参数中
您不能直接从 UploadPage 调用 setState 的原因是因为 setState 是一个 class 方法,所以它总是只与直接封闭的 class 实例的状态相关联。如果你想改变 Widget 树中更高层的 Widget 的状态,标准方法是将回调传递给子组件。
在您的情况下,您可以向 UploadPage 小部件添加一个新的 属性 - 例如 onButtonPressed:
class UploadPage extends StatelessWidget {
final Function onButtonPressed;
UploadPage({required this.onButtonPressed});
@override
Widget build(BuildContext context) {
return YourWidget(
// ...
child: RaisedButton(onPressed: onButtonPressed),
// ...
);
}
}
然后:
AnimatedContainer(
// ...
child: clickedCentreFAB
? UploadPage(
onButtonPressed: () {
setState(() { return clickedCentreFAB = false; });
},
)
: null,
)
)
顺便说一句,在某个时刻,您的应用程序的状态可能非常复杂,足以保证像 bloc
、redux
等解决方案 - 但是,对于这种特定情况,这些可能是矫枉过正。
如果您发现自己必须通过小部件树的多个级别传递回调和属性,那么 provider
会非常有用。
如果动作、状态和视图之间的映射变得非常复杂,那么 bloc
或 redux
可以帮助将结构强加到您的项目中并使其更容易推理,尽管您会通常需要编写更多代码才能完成相同的任务。