我刚开始在Flutter中学习GetX,因为我正在尝试改进我的应用程序状态。用户可以选择“即时”或“约会”,所以如果点击“即时”,将创建一个firebase文档,用户现在处于搜索状态。主要目标是当用户返回主页时,在底部显示一个小部件,例如“正在搜索用户..."。因此,我对国家管理的介绍
错误
Exception has occurred.
FlutterError (setState() or markNeedsBuild() called during build.
This Obx widget cannot be marked as needing to build because the framework is already
in the process of building widgets. A widget can be marked as needing to be built
during the build phase only if one of its ancestors is currently building. This
exception is allowed because the framework builds parent widgets before children,
which means a dirty descendant will always be built. Otherwise, the framework might
not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was:
Obx
The widget which was currently being built when the offending call was made was:
FindInstantWidget)
订单_屏幕.省道
class FindInstantWidget extends GetWidget {
const FindInstantWidget({Key? key, required this.text, required this.docId})
: super(key: key);
final String? text;
final String? docId;
@override
Widget build(BuildContext context) {
final controller = Get.put(SearchingController());
if (controller.isSearching.isFalse) {
controller.startSearch(docId);
}
return Obx(() => controller.isAccepted.isFalse
? Scaffold(
body: Container(
margin: const EdgeInsets.symmetric(vertical: 20, horizontal: 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: const EdgeInsets.all(20),
child: const CircularProgressIndicator(
backgroundColor: Colors.grey,
color: Colors.purple,
strokeWidth: 5,
),
),
Container(
margin: const EdgeInsets.all(20),
child: Text("Searching for $text"),
),
const SizedBox(height: 16),
ButtonWidget(
text: 'Cancel',
onClicked: () async {
//Database().deleteInstant(docId);
//Navigator.pop(context);
controller.stopSearch();
DocumentReference docRef =
_firestore.collection('jobs').doc(docId);
Database().deleteInstant(docRef);
Get.offAll(() => LandingPage(title: "Landing Page"));
})
],
),
),
)
: const Scaffold(
body: Text("Found someone for you!"),
));
}
}
搜索控制器.dart
import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:get/get.dart';
class SearchingController extends GetxController {
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
RxBool isSearching = false.obs;
RxBool isAccepted = false.obs;
RxString? uidAcceptor;
final jobType = Rxn<String>();
final docId = Rxn<String>();
StreamSubscription? _streamSubscription;
void startSearch(String? id) {
DocumentReference docRef = _firestore.collection('jobs').doc(id);
docId.value = docRef.id;
isSearching.value = true;
try {
_streamSubscription = docRef.snapshots().listen((e) async {
Map a = e.data() as Map<String, dynamic>;
uidAcceptor?.value = a['uidAccepted'];
isAccepted.value = a['isAccepted'];
jobType.value = a['jobType'];
});
update();
} catch (e) {
print(e);
}
}
void stopSearch() {
isSearching.value = false;
_streamSubscription?.cancel();
}
}
着陆屏幕.dart
class LandingPage extends GetWidget {
LandingPage({Key? key, required this.title}) : super(key: key);
final String title;
BottomNavigationController bottomNavigationController =
Get.put(BottomNavigationController());
SearchingController searchingController = Get.put(SearchingController());
final screens = [
const HomePage(),
const OrderPage(),
const AccountPage(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Obx(() => Stack(alignment: Alignment.center, children: [
IndexedStack(
index: bottomNavigationController.selectedIndex.value,
children: screens,
),
searchingController.isSearching.isTrue
? Positioned(
bottom: 10,
child: GestureDetector(
onTap: () {
Get.to(FindInstantWidget(
text: searchingController.jobType.value,
docId: searchingController.docId.value));
},
child: Container(
decoration: const BoxDecoration(color: Colors.grey),
width: 250,
child: Padding(
padding: const EdgeInsets.all(10),
child: Text(
"Searching for ${searchingController.jobType.value}...",
style: const TextStyle(
fontFamily: 'Roboto',
fontSize: 16,
color: Colors.black,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal),
textAlign: TextAlign.center,
),
),
)))
: const SizedBox(width: 0, height: 0)
])),
bottomNavigationBar: Obx(
() => BottomNavigationBar(
currentIndex: bottomNavigationController.selectedIndex.value,
fixedColor: Colors.green,
items: const [
BottomNavigationBarItem(
label: "Home",
icon: Icon(Icons.home),
),
BottomNavigationBarItem(
label: "Orders",
icon: Icon(Icons.article_outlined),
),
BottomNavigationBarItem(
label: "Account",
icon: Icon(Icons.account_circle_outlined),
),
],
onTap: (index) => bottomNavigationController.changeIndex(index)),
));
}
}
它以前是工作的,当我回到登陆界面时,小部件显示为它应该的样子,但当我学习删除它并取消firebase收听订阅时,它似乎不再正常工作了。如果我点击导航栏上的其他图标重新加载登陆小部件,小部件会出现。似乎GetX没有正确更新视图?
我头晕的原因可能是searchingController.dart中的这一行(也突出显示)isSearching.value = true;
异常的SS(https://i.stack.imgur.com/AOnOV.png)
如果我把它移到try-catch块中,它几乎不起作用,但它似乎延长了我从所有其他问题中陷入疯狂的时间。
当初始化我的控制器时,这确实出现在我的调试控制台上,它一直困扰着我,但我对“GetLifeCycleBase?”
[GETX] Instance "GetMaterialController" has been created
[GETX] Instance "GetMaterialController" has been initialized
[GETX] Instance "GetLifeCycleBase?" is not registered.
[GETX] Instance "AuthController" has been created
[GETX] Instance "AuthController" has been initialized
[GETX] Instance "BottomNavigationController" has been created
[GETX] Instance "BottomNavigationController" has been initialized
1条答案
按热度按时间aor9mmx11#
几乎可以肯定,这是因为
FindInstantWidget
上的构建函数中有controller.startSearch(docId);
。而不是这个:
试试这个: