[英]Using a Switch() widget with GetX/Obx()
I am back with the question: How can I use the Switch() widget with GetX/Obx()?我又来了一个问题:如何将 Switch() 小部件与 GetX/Obx() 一起使用? At many places i have read that with GetX/Obx no need of StatefullWidget.在很多地方,我都读过 GetX/Obx 不需要 StatefullWidget。 So in my app I use only StatelessWidgets.所以在我的应用程序中,我只使用 StatelessWidgets。 Problem is that i can not make a Switch() working because SetState() is not usable in StatelessWidget.问题是我无法使 Switch() 工作,因为 SetState() 在 StatelessWidget 中不可用。
Can someone help, please?有人可以帮忙吗? Thank for your kindness.谢谢你的好意。 A.KOTE A.KOTE
For simple Switch state toggle you should not use a controller.对于简单的开关 state 切换,您不应使用 controller。 Controller is for more complex business logic implementation which can be shared among screens. Controller 用于更复杂的业务逻辑实现,可以在屏幕之间共享。 You can use ValueBuilder
from Get
package which can give desired result with less code.您可以使用Get
ValueBuilder
中的 ValueBuilder,它可以用更少的代码提供所需的结果。 Here is an example:这是一个例子:
Center(
child: ValueBuilder<bool>(
initialValue: true,
builder: (isChecked, updateFn) => Switch(
value: isChecked,
onChanged: (newValue) => updateFn(newValue),
),
),
),
I can give you an example and then you can implement in your code.我可以给你一个例子,然后你可以在你的代码中实现。
You can use a GetxController to handle the widget state.您可以使用 GetxController 来处理小部件 state。
Counter example:反例:
class YourController extends GetxController {
//The current value
int counter = 0;
void increment() {
counter++;
update(); // use update() to update counter variable on UI when increment be called
}
}
Then in your statelessWidget you can listen.然后在你的 statelessWidget 你可以听。
class YourWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: GetBuilder<YourController>(
init: Controller(), // INIT IT ONLY THE FIRST TIME
builder: (_) => Text(
'${_.counter}',
),
),
));
}
}
DOCS: https://github.com/jonataslaw/getx/blob/master/documentation/en_US/state_management.md#simple-state-manager文档: https://github.com/jonataslaw/getx/blob/master/documentation/en_US/state_management.md#simple-state-manager
How can you update the value?如何更新值?
Add a line to your controller在您的 controller 中添加一行
class YourController extends GetxController {
//New line added
static YourController get to => Get.find();
int counter = 0;
void increment() {
counter++;
update(); // use update() to update counter variable on UI when increment be called
}
}
Update the UI更新用户界面
return Scaffold(
// body: /*... */
floatingActionButton: FloatingActionButton(
child: Text('Hit'),
onPressed: () {
//Apply the logic to your Switch widget
YourController.to.update();
},
),
);
}
Here's a copy/paste example of using GetX with a Switch
widget, within a StatelessWidget
.这是在StatelessWidget
中使用 GetX 和Switch
小部件的复制/粘贴示例。
import 'package:flutter/material.dart';
import 'package:get/get.dart';
/// GetX Controller for holding Switch's current value
class SwitchX extends GetxController {
RxBool on = false.obs; // our observable
// swap true/false & save it to observable
void toggle() => on.value = on.value ? false : true;
}
/// Stateless Page here
class SwitchGetxPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
SwitchX sx = Get.put(SwitchX()); // Instantiate Get Controller, *in* build()
return Scaffold(
appBar: AppBar(
title: Text('Switch Field'),
),
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Obx will rebuild Text & Switch when "on" observable changes
Obx(() => Text('Switch Setting: ${sx.on}')),
Obx(() => Switch(
onChanged: (val) => sx.toggle(),
value: sx.on.value),
)
],
),
),
),
);
}
}
With GetX you don't need StatefulWidgets
because you're holding "state" outside of widgets and "inside" a GetxController
.使用 GetX,您不需要StatefulWidgets
,因为您在小部件之外和“内部”持有“状态” GetxController
。
In the example above, RxBool on = false.obs
is the "state" of your application.在上面的示例中, RxBool on = false.obs
是应用程序的“状态”。 It will be true
or false
throughout the life of your app.在您的应用程序的整个生命周期中,这将是true
或false
。
When Switch's
value changes, any widgets you need rebuilt, put them in Obx
, GetX
or GetBuilder
and use the observable variable.当Switch's
值发生变化时,您需要重建的任何小部件,将它们放入Obx
, GetX
或GetBuilder
并使用 observable 变量。
Obx
, GetX
will rebuild themselves whenever their observable changes. Obx
, GetX
将在其可观察到的变化时重建自己。 GetBuilder
requires you call update()
for it to rebuild. GetBuilder
要求您调用update()
来重建它。 Just like a setState()
call.就像setState()
调用一样。
Obx
in Example?为什么在示例中有两个Obx
? To make painfully obvious that Obx/GetX
must directly wrap an observable variable.为了使Obx/GetX
必须直接包装一个可观察的变量,这一点非常明显。
GetX
asks you to use observable variables directly in Obx/GetX
, not further nested down, like in child of a child. GetX
要求您直接在Obx/GetX
中使用可观察变量,而不是像在孩子的孩子中那样进一步嵌套。
For example, this below, will throw an Error:例如,下面的这个,会抛出一个错误:
class SwitchGetxPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
SwitchX sx = Get.put(SwitchX());
return Scaffold(
appBar: AppBar(
title: Text('Switch Field'),
),
body: SafeArea(
child: Center(
child: Obx(() => MyTextSwitch(sx)), // don't do this, will explode
),
),
);
}
}
class MyTextSwitch extends StatelessWidget {
final SwitchX sx;
MyTextSwitch(this.sx);
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Switch Setting: ${sx.on}'),
Switch(
onChanged: (val) => sx.toggle(),
value: sx.on.value)
],
);
}
}
This version below is still OK, but not used in first example, as it may lead to bad habits (like rebuilding widgets that don't need it) & errors like the example immediately above.下面的这个版本仍然可以,但没有在第一个示例中使用,因为它可能会导致不良习惯(例如重建不需要它的小部件)和上面示例中的错误。 Just remember that Obx/GetX
must have an observable in its child:请记住, Obx/GetX
的子项中必须有一个 observable:
class SwitchGetxPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
SwitchX sx = Get.put(SwitchX());
return Scaffold(
appBar: AppBar(
title: Text('Switch Field'),
),
body: SafeArea(
child: Center(
child: Obx( // still OK, but rebuilds Column unnecessarily
() => Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Switch Setting: ${sx.on}'),
Switch(
onChanged: (val) => sx.toggle(),
value: sx.on.value)
],
),
),
),
),
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.