我又来了一个问题:如何将 Switch() 小部件与 GetX/Obx() 一起使用?在很多地方,我都读过 GetX/Obx 不需要 StatefullWidget。所以在我的应用程序中,我只使用 StatelessWidgets。问题是我无法使 Switch() 工作,因为 SetState() 在 StatelessWidget 中不可用。
有人可以帮忙吗?谢谢你的好意。A.KOTE
我又来了一个问题:如何将 Switch() 小部件与 GetX/Obx() 一起使用?在很多地方,我都读过 GetX/Obx 不需要 StatefullWidget。所以在我的应用程序中,我只使用 StatelessWidgets。问题是我无法使 Switch() 工作,因为 SetState() 在 StatelessWidget 中不可用。
有人可以帮忙吗?谢谢你的好意。A.KOTE
这是一个使用 GetX 和Switch
小部件的复制/粘贴示例,在StatelessWidget
.
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),
)
],
),
),
),
);
}
}
使用 GetX,您不需要StatefulWidgets
,因为您在小部件之外和“内部”持有“状态” a GetxController
.
在上面的示例中,RxBool on = false.obs
是应用程序的“状态”。它将是true
或false
在您的应用程序的整个生命周期中。
当Switch's
值发生变化时,您需要重建的任何小部件,将它们放入Obx
,GetX
或GetBuilder
使用可观察变量。
Obx
,GetX
将在可观察到的变化时重建自己。 GetBuilder
需要你要求update()
它重建。就像setState()
打电话一样。
Obx
在示例中有两个?为了使痛苦显而易见,Obx/GetX
必须直接包装一个可观察变量。
GetX
要求您直接在 中使用可观察变量Obx/GetX
,而不是像在孩子的孩子中那样进一步嵌套。
例如,下面的这个,会抛出一个错误:
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)
],
);
}
}
下面的这个版本仍然可以,但没有在第一个示例中使用,因为它可能会导致不良习惯(例如重建不需要它的小部件)和上面示例中的错误。请记住,Obx/GetX
它的孩子必须有一个可观察的:
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)
],
),
),
),
),
);
}
}
对于简单的 Switch 状态切换,您不应使用控制器。控制器用于更复杂的业务逻辑实现,可以在屏幕之间共享。您可以使用ValueBuilder
fromGet
包,它可以用更少的代码提供所需的结果。这是一个例子:
Center(
child: ValueBuilder<bool>(
initialValue: true,
builder: (isChecked, updateFn) => Switch(
value: isChecked,
onChanged: (newValue) => updateFn(newValue),
),
),
),
我可以给你一个例子,然后你可以在你的代码中实现。
您可以使用 GetxController 来处理小部件状态。
反例:
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
}
}
然后在你的 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}',
),
),
));
}
}
如何更新值?
在控制器中添加一条线
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
}
}
更新用户界面
return Scaffold(
// body: /*... */
floatingActionButton: FloatingActionButton(
child: Text('Hit'),
onPressed: () {
//Apply the logic to your Switch widget
YourController.to.update();
},
),
);
}