Flutter 使用小部件外部的GetX观察列表
我已经做了一些繁重的计算,然后在收到带有结果的列表时运行for循环,将它们添加到可观察列表中,其中items var items=[].obs 问题是,我正试图从splash控制器观察项目列表,一旦该列表[]我将导航到另一个屏幕,因此在onInit()中我有以下代码:Flutter 使用小部件外部的GetX观察列表,flutter,dart,getx,Flutter,Dart,Getx,我已经做了一些繁重的计算,然后在收到带有结果的列表时运行for循环,将它们添加到可观察列表中,其中items var items=[].obs 问题是,我正试图从splash控制器观察项目列表,一旦该列表[]我将导航到另一个屏幕,因此在onInit()中我有以下代码: class SplashController extends GetxController { @override void onInit() { final ItemsController _itemsContr
class SplashController extends GetxController {
@override
void onInit() {
final ItemsController _itemsController = Get.put(ItemsController());
// TODO: implement onInit
super.onInit();
ever(_itemsController.items, (newItems) {
print('new items here $newItems');
});
}
}
尽管填充了itemsController.items(在for循环之后,我打印了itemsController.items,并且它不是空的),但是添加项目时,splash控制器上的工作进程不会触发
我做错了什么?这是使用Getx观察小部件外部变量的正确方法吗?
有人能帮我吗
编辑:在项目控制器中,我以这种方式添加项目
add(item) => items.add(item)
这里有两个控制器,其中一个
ever
工作者监听另一个控制器的事件,其中该控制器的事件来自于在隔离中生成的数据
与任何其他异步数据源相比,我不知道在隔离中生成数据有什么特别之处,但我对隔离并不太熟悉
控制器
最后,调试输出结果显示处理可观察事件的工作人员(接收到的项目…
):
非隔离页中的控制器
使用上述相同控制器的示例,没有有状态小部件页面和所有隔离内容的干扰
class SplashX extends GetxController {
ItemsX itemsX;
SplashX({this.itemsX});
@override
void onInit() {
super.onInit();
ever(itemsX.items, (items) => print('Received items: $items'));
}
}
class ItemsX extends GetxController {
RxList<String> items = RxList<String>();
void add(String item) {
items.add(item);
}
/// Only relevant for SimplePage
List<Widget> get texts => items.map((item) => Text('$item')).toList();
}
class SimplePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
ItemsX ix = Get.put(ItemsX());
SplashX sx = Get.put(SplashX(itemsX: ix));
return Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
flex: 10,
child: Obx(
() => ListView(
children: ix.texts,
),
),
),
Expanded(
flex: 1,
child: RaisedButton(
child: Text('Add'),
onPressed: () => ix.add('more...'),
)
)
],
),
),
);
}
}
class SplashX扩展了GetxController{
ItemsX ItemsX;
SplashX({this.itemsX});
@凌驾
void onInit(){
super.onInit();
曾经(itemsX.items,(items)=>print('receiveitems:$items');
}
}
类ItemsX扩展了GetxController{
RxList items=RxList();
无效添加(字符串项){
项目。添加(项目);
}
///仅与SimplePage相关
List get Text=>items.map((item)=>Text('$item')).toList();
}
类SimplePage扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
ItemsX ix=Get.put(ItemsX());
SplashX-sx=Get.put(SplashX(itemsX:ix));
返回脚手架(
正文:安全区(
子:列(
儿童:[
扩大(
弹性:10,
儿童:Obx(
()=>列表视图(
儿童:九、文本,
),
),
),
扩大(
弹性:1,
孩子:升起按钮(
子项:文本('Add'),
onPressed:()=>ix.add('more…'),
)
)
],
),
),
);
}
}
这里有两个控制器,其中一个工作人员监听另一个控制器的事件,其中该控制器的事件来自于在隔离中生成的数据
与任何其他异步数据源相比,我不知道在隔离中生成数据有什么特别之处,但我对隔离并不太熟悉
控制器
最后,调试输出结果显示处理可观察事件的工作人员(接收到的项目…
):
非隔离页中的控制器
使用上述相同控制器的示例,没有有状态小部件页面和所有隔离内容的干扰
class SplashX extends GetxController {
ItemsX itemsX;
SplashX({this.itemsX});
@override
void onInit() {
super.onInit();
ever(itemsX.items, (items) => print('Received items: $items'));
}
}
class ItemsX extends GetxController {
RxList<String> items = RxList<String>();
void add(String item) {
items.add(item);
}
/// Only relevant for SimplePage
List<Widget> get texts => items.map((item) => Text('$item')).toList();
}
class SimplePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
ItemsX ix = Get.put(ItemsX());
SplashX sx = Get.put(SplashX(itemsX: ix));
return Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
flex: 10,
child: Obx(
() => ListView(
children: ix.texts,
),
),
),
Expanded(
flex: 1,
child: RaisedButton(
child: Text('Add'),
onPressed: () => ix.add('more...'),
)
)
],
),
),
);
}
}
class SplashX扩展了GetxController{
ItemsX ItemsX;
SplashX({this.itemsX});
@凌驾
void onInit(){
super.onInit();
曾经(itemsX.items,(items)=>print('receiveitems:$items');
}
}
类ItemsX扩展了GetxController{
RxList items=RxList();
无效添加(字符串项){
项目。添加(项目);
}
///仅与SimplePage相关
List get Text=>items.map((item)=>Text('$item')).toList();
}
类SimplePage扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
ItemsX ix=Get.put(ItemsX());
SplashX-sx=Get.put(SplashX(itemsX:ix));
返回脚手架(
正文:安全区(
子:列(
儿童:[
扩大(
弹性:10,
儿童:Obx(
()=>列表视图(
儿童:九、文本,
),
),
),
扩大(
弹性:1,
孩子:升起按钮(
子项:文本('Add'),
onPressed:()=>ix.add('more…'),
)
)
],
),
),
);
}
}
继续,但不使用StatefulWidget,即无设置状态用法
SplashX中的ever
工作人员将接收从隔离生成的项目。无状态小部件页面将显示从隔离发出的最新项
Splash控制器+曾经
工人
项目控制员
无状态页面
类MyHomePageStateless扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
ItemsX ix=Get.put(ItemsX());//实例化ItemsController
IsolateX isox=Get.put(IsolateX(itemsX:ix));
SplashX-sx=Get.put(SplashX(itemsX:ix));
返回脚手架(
appBar:appBar(
标题:文本(“隔离无状态”),
),
正文:中(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
GetX(
生成器:(ix)=>文本(ix.items.isNotEmpty?ix.items.last:“”),
),
],
),
),
浮动操作按钮:GetBuilder(
生成器:(_ix)=>浮动操作按钮(
按下按钮:_ix.运行?isox.停止:isox.启动,
工具提示:_ix.running?'Timer stop':'Timer start',
子项:_ix.running?图标(Icons.stop):图标(Icons.play_箭头),
),
),
);
}
}
继续,但不使用StatefulWidget,即无设置状态用法
SplashX中的ever
工作人员将接收从隔离生成的项目。无状态小部件页面将显示从隔离发出的最新项
Splash控制器+曾经
void _handleMessage(dynamic data) {
//print('RECEIVED: ' + data);
ix.add(data); // update observable
setState(() {
notification = data;
});
}
[GETX] "ItemsX" has been initialized
[GETX] "SplashX" has been initialized
I/flutter (19012): SEND: notification 1
I/flutter (19012): Received items: [notification 1]
I/flutter (19012): SEND: notification 2
I/flutter (19012): Received items: [notification 1, notification 2]
I/flutter (19012): SEND: notification 3
I/flutter (19012): Received items: [notification 1, notification 2, notification 3]
I/flutter (19012): done!
class SplashX extends GetxController {
ItemsX itemsX;
SplashX({this.itemsX});
@override
void onInit() {
super.onInit();
ever(itemsX.items, (items) => print('Received items: $items'));
}
}
class ItemsX extends GetxController {
RxList<String> items = RxList<String>();
void add(String item) {
items.add(item);
}
/// Only relevant for SimplePage
List<Widget> get texts => items.map((item) => Text('$item')).toList();
}
class SimplePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
ItemsX ix = Get.put(ItemsX());
SplashX sx = Get.put(SplashX(itemsX: ix));
return Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
flex: 10,
child: Obx(
() => ListView(
children: ix.texts,
),
),
),
Expanded(
flex: 1,
child: RaisedButton(
child: Text('Add'),
onPressed: () => ix.add('more...'),
)
)
],
),
),
);
}
}
class SplashX extends GetxController {
ItemsX itemsX;
SplashX({this.itemsX});
@override
void onInit() {
super.onInit();
ever(itemsX.items, (items) => print('Ever items: $items'));
}
}
class ItemsX extends GetxController {
RxList<String> items = RxList<String>();
bool running = false;
void add(String item) {
items.add(item);
}
void updateStatus(bool isRunning) {
running = isRunning;
update();
}
void reset() {
items.clear();
}
/// Only relevant for UnusedControllerPage
List<Widget> get texts => items.map((item) => Text('$item')).toList();
}
class IsolateX extends GetxController {
IsolateX({this.itemsX});
ItemsX itemsX;
Isolate _isolate;
static int _counter = 0;
ReceivePort _receivePort;
bool running = false;
static void _checkTimer(SendPort sendPort) async {
Timer.periodic(Duration(seconds: 1), (Timer t) {
_counter++;
String msg = 'notification ' + _counter.toString();
print('SEND: ' + msg);
sendPort.send(msg);
});
}
void _handleMessage(dynamic data) {
itemsX.add(data); // update observable
}
void updateStatus(bool isRunning) {
running = isRunning;
update();
}
void start() async {
itemsX.reset();
updateStatus(true);
_receivePort = ReceivePort();
_isolate = await Isolate.spawn(_checkTimer, _receivePort.sendPort);
_receivePort.listen(_handleMessage, onDone:() {
print("done!");
});
}
void stop() {
if (_isolate != null) {
updateStatus(false);
_receivePort.close();
_isolate.kill(priority: Isolate.immediate);
_isolate = null;
}
}
}
class MyHomePageStateless extends StatelessWidget {
@override
Widget build(BuildContext context) {
ItemsX ix = Get.put(ItemsX()); // Instantiate ItemsController
IsolateX isox = Get.put(IsolateX(itemsX: ix));
SplashX sx = Get.put(SplashX(itemsX: ix));
return Scaffold(
appBar: AppBar(
title: Text('Isolate Stateless'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
GetX<ItemsX>(
builder: (ix) => Text(ix.items.isNotEmpty ? ix.items.last : ''),
),
],
),
),
floatingActionButton: GetBuilder<IsolateX>(
builder: (_ix) => FloatingActionButton(
onPressed: _ix.running ? isox.stop : isox.start,
tooltip: _ix.running ? 'Timer stop' : 'Timer start',
child: _ix.running ? Icon(Icons.stop) : Icon(Icons.play_arrow),
),
),
);
}
}