GetX + Switch
Вот пример копирования / вставки использования 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 + State
С GetX вам не нужно StatefulWidgets
, потому что вы храните состояние вне виджетов и внутри 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)
],
),
),
),
),
);
}
}
person
Baker
schedule
05.04.2021