Flutter 从相关小部件更改状态 class
Flutter change state from related widget class
让我们假设一个class“SpecialButton”及其状态-Class“SpecialButtonState”
class SpecialButton extends StatefulWidget {
bool active = false;
SpecialButton({Key key}) : super(key: key);
@override
SpecialButtonState createState() => SpecialButtonState();
}
class SpecialButtonState extends State<SpecialButton> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
decoration:
BoxDecoration(color: this.widget.active ? COLOR_1 : COLOR_2),
child: null);
}
}
在父窗口小部件中,我管理了几个这样的按钮。因此,我想给他们分配一个状态。我尝试的解决方案是在 SpecialButton class 中引入一个标志“active”,我可以很容易地从父窗口小部件将其设置为 true 或 false。然后我可以在状态 class 的构建函数中使用它来为按钮着色。不幸的是,这并不完全有效,因为它不会立即更新按钮(它需要某种状态更新,例如通过将鼠标悬停在元素上)。
我的第二个想法是将此标志作为 SpecialButtonState 的适当状态引入 class
class SpecialButton extends StatefulWidget {
SpecialButton({Key key}) : super(key: key);
@override
SpecialButtonState createState() => SpecialButtonState();
}
class SpecialButtonState extends State<SpecialButton> {
bool active;
@override
void initState() {
super.initState();
this.active = false;
}
activate() {
this.setState(() {
active = true;
});
}
deactivate() {
this.setState(() {
active = false;
});
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(color: this.active ? COLOR_1 : COLOR_2),
child: null);
}
}
据我所知,这是使用 flutter 的正确方法,但似乎我无法从 SpecialButton Class 或父级 Class 包含小部件。
所以我的问题是:如何(直接或间接通过函数)从相应的 StatefulWidget Class 或包含它的 Parent Widget 修改 State?
在 Stack Overflow 上已经有一些类似的问题,我可以在其中找到关于使用或不使用全局键的提示,我发现这种行为具有误导性。此外,由于 flutter 的快速发展,它们可能已经过时,所以我再次针对这个确切的用例问这个(类似的)问题。
编辑:我忘了提到这个标志在创建后将被更改是至关重要的,因此它将在其生命周期内多次更改。这需要重新绘制小部件。
在 SpecialButton
情况下,没有必要使用有状态小部件。您可以使用无状态小部件和键处理 active
标志。示例代码:
class SomeParent extends StatefulWidget {
const SomeParent({Key key}) : super(key: key);
@override
State<SomeParent> createState() => SomeParentState();
}
class SomeParentState extends State<SomeParent> {
bool _button1IsActive = false;
bool _button2IsActive = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
SpecialButton(
key: UniqueKey(),
active: _button1IsActive,
),
SizedBox(height: 8),
SpecialButton(
key: UniqueKey(),
active: _button2IsActive,
),
SizedBox(height: 16),
TextButton(
child: Text('Toggle button 1'),
onPressed: () {
setState(() {
_button1IsActive = !_button1IsActive;
});
},
),
SizedBox(height: 8),
TextButton(
child: Text('Toggle button 2'),
onPressed: () {
setState(() {
_button2IsActive = !_button2IsActive;
});
},
),
],
),
);
}
}
class SpecialButton extends StatelessWidget {
final bool active;
const SpecialButton({Key key, this.active = false}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: 40,
width: 40,
decoration: BoxDecoration(color: active ? Colors.red : Colors.blue),
);
}
}
SomeParent
是我的幻想,只是举个例子。不知道你的 parent 是什么。
键在这里很重要。他们告诉小部件树何时应该重建具有相同类型(例如SpecialButton
)的特定小部件。
请尝试此方法,它应该有效。
正如 nvoigt 所说,您的按钮甚至可以是无状态小部件,但它们的父级应该是有状态的,您应该为它们提供相应的值。例如:
import 'package:flutter/material.dart';
class Parent extends StatefulWidget {
@override
_ParentState createState() => _ParentState();
}
class _ParentState extends State<Parent> {
bool isEnabled = false;
@override
Widget build(BuildContext context) {
return Column(
children: [
StateLessButton1(isEnabled: isEnabled),
StateLessButton1(isEnabled: !isEnabled),
FloatingActionButton(onPressed: (){
setState(() {
isEnabled = !isEnabled;
});
})
],
);
}
}
现在这取决于您何时更改该值。如果您想在按钮内更改它,我建议您使用 class 和 ChangeNotifier 以及其中的一个函数来更改值。否则我建议不要将你的树分成多个文件
让我们假设一个class“SpecialButton”及其状态-Class“SpecialButtonState”
class SpecialButton extends StatefulWidget {
bool active = false;
SpecialButton({Key key}) : super(key: key);
@override
SpecialButtonState createState() => SpecialButtonState();
}
class SpecialButtonState extends State<SpecialButton> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
decoration:
BoxDecoration(color: this.widget.active ? COLOR_1 : COLOR_2),
child: null);
}
}
在父窗口小部件中,我管理了几个这样的按钮。因此,我想给他们分配一个状态。我尝试的解决方案是在 SpecialButton class 中引入一个标志“active”,我可以很容易地从父窗口小部件将其设置为 true 或 false。然后我可以在状态 class 的构建函数中使用它来为按钮着色。不幸的是,这并不完全有效,因为它不会立即更新按钮(它需要某种状态更新,例如通过将鼠标悬停在元素上)。
我的第二个想法是将此标志作为 SpecialButtonState 的适当状态引入 class
class SpecialButton extends StatefulWidget {
SpecialButton({Key key}) : super(key: key);
@override
SpecialButtonState createState() => SpecialButtonState();
}
class SpecialButtonState extends State<SpecialButton> {
bool active;
@override
void initState() {
super.initState();
this.active = false;
}
activate() {
this.setState(() {
active = true;
});
}
deactivate() {
this.setState(() {
active = false;
});
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(color: this.active ? COLOR_1 : COLOR_2),
child: null);
}
}
据我所知,这是使用 flutter 的正确方法,但似乎我无法从 SpecialButton Class 或父级 Class 包含小部件。
所以我的问题是:如何(直接或间接通过函数)从相应的 StatefulWidget Class 或包含它的 Parent Widget 修改 State?
在 Stack Overflow 上已经有一些类似的问题,我可以在其中找到关于使用或不使用全局键的提示,我发现这种行为具有误导性。此外,由于 flutter 的快速发展,它们可能已经过时,所以我再次针对这个确切的用例问这个(类似的)问题。
编辑:我忘了提到这个标志在创建后将被更改是至关重要的,因此它将在其生命周期内多次更改。这需要重新绘制小部件。
在 SpecialButton
情况下,没有必要使用有状态小部件。您可以使用无状态小部件和键处理 active
标志。示例代码:
class SomeParent extends StatefulWidget {
const SomeParent({Key key}) : super(key: key);
@override
State<SomeParent> createState() => SomeParentState();
}
class SomeParentState extends State<SomeParent> {
bool _button1IsActive = false;
bool _button2IsActive = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
SpecialButton(
key: UniqueKey(),
active: _button1IsActive,
),
SizedBox(height: 8),
SpecialButton(
key: UniqueKey(),
active: _button2IsActive,
),
SizedBox(height: 16),
TextButton(
child: Text('Toggle button 1'),
onPressed: () {
setState(() {
_button1IsActive = !_button1IsActive;
});
},
),
SizedBox(height: 8),
TextButton(
child: Text('Toggle button 2'),
onPressed: () {
setState(() {
_button2IsActive = !_button2IsActive;
});
},
),
],
),
);
}
}
class SpecialButton extends StatelessWidget {
final bool active;
const SpecialButton({Key key, this.active = false}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: 40,
width: 40,
decoration: BoxDecoration(color: active ? Colors.red : Colors.blue),
);
}
}
SomeParent
是我的幻想,只是举个例子。不知道你的 parent 是什么。
键在这里很重要。他们告诉小部件树何时应该重建具有相同类型(例如SpecialButton
)的特定小部件。
请尝试此方法,它应该有效。
正如 nvoigt 所说,您的按钮甚至可以是无状态小部件,但它们的父级应该是有状态的,您应该为它们提供相应的值。例如:
import 'package:flutter/material.dart';
class Parent extends StatefulWidget {
@override
_ParentState createState() => _ParentState();
}
class _ParentState extends State<Parent> {
bool isEnabled = false;
@override
Widget build(BuildContext context) {
return Column(
children: [
StateLessButton1(isEnabled: isEnabled),
StateLessButton1(isEnabled: !isEnabled),
FloatingActionButton(onPressed: (){
setState(() {
isEnabled = !isEnabled;
});
})
],
);
}
}
现在这取决于您何时更改该值。如果您想在按钮内更改它,我建议您使用 class 和 ChangeNotifier 以及其中的一个函数来更改值。否则我建议不要将你的树分成多个文件