英文:
Flutter Getx. Listening to the list in Obx error. How to fix it?
问题
我在Flutter中使用Provider更新了ListView中的列表。现在我正试图使用Getx做同样的事情。我遇到了一个错误。我会在下面展示代码示例。我在互联网上找不到任何相关信息。如果你能帮忙,我会非常高兴。提前感谢大家。
HomeController.dart
class HomeController extends GetxController {
final RxList<Category> category = <Category>[].obs;
final RxList<Post> slide = <Post>[].obs;
final RxList<Post> posts = <Post>[].obs;
Future<void> getPost() async {
await Service().getPost(start.value, limit).then((value) {
if (value.isNotEmpty) {
if (value.length < limit) {
netStatus.value = 3;
isLoading.value = false;
} else {
isLoading.value = true;
}
posts.addAll(value);
start.value += limit;
}
});
}
}
Post.dart - 这个方法在Provider中运行得很好,我想用Obx包装它在Getx中监听它
List<Widget> post(BuildContext context) {
final CacheManager cacheManager = CacheService().cacheManager;
HomeController controller = Get.find<HomeController>();
List<Widget> posts = [
...controller.posts.map((post) => postCard(
context,
post,
controller.category[int.parse(post.categoryId!) - 1],
cacheManager,
)),
];
return posts;
}
Home.dart
class Home extends GetView<HomeController> {
const Home({super.key});
@override
Widget build(BuildContext context) {
List<Widget> widgets = [
Obx(() => slider()), //**Slider在Obx下运行得很好**
...post(context), /***我的问题从这里开始。我需要将它包装在Obx中以监听列表的内容。
我可以包装滑块小部件,但我不能包装post。这对ListView中的懒加载是必需的。
否则,所有的元素都会加载而不下降。***/
];
return Obx(() {
if (controller.posts.isEmpty) {
return loadHelper(context, controller.netStatus.value, () {
controller.getCategory();
});
} else {
return RefreshIndicator(
edgeOffset: MediaQuery.of(context).padding.top,
onRefresh: () => controller.onRefresh(),
child: Obx(
() => ListView.builder(
shrinkWrap: true,
controller: controller.scrollController,
itemCount: widgets.length + 1,
itemBuilder: (context, index) {
if (index < widgets.length) {
return Obx(() => widgets[index]);
} else {
return loadHelper(context, controller.netStatus.value, () {
controller.getSlide();
});
}
},
),
));
}
});
}
}
请帮我解决这个问题。谢谢大家。
英文:
I updated the list in listview with Provider in Flutter. Now I'm trying to do the same with Getx. I am getting an error. I will show the code example below. I couldn't find anything on the Internet about this. I would be very happy if you help. In advance, I express my thanks to everyone.
HomeController.dart
class HomeController extends GetxController {
final RxList<Category> category = <Category>[].obs;
final RxList<Post> slide = <Post>[].obs;
final RxList<Post> posts = <Post>[].obs;
Future<void> getPost() async {
await Service().getPost(start.value, limit).then((value) {
if (value.isNotEmpty) {
if (value.length < limit) {
netStatus.value = 3;
isLoading.value = false;
} else {
isLoading.value = true;
}
posts.addAll(value);
start.value += limit;
}
});
}
}
Post.dart - This Method works very well with Provider, I want to wrap it with Obx at Getx to listen to it
List<Widget> post(BuildContext context) {
final CacheManager cacheManager = CacheService().cacheManager;
HomeController controller = Get.find<HomeController>();
List<Widget> posts = [
...controller.posts.map((post) => postCard(
context,
post,
controller.category[int.parse(post.categoryId!) - 1],
cacheManager,
)),
];
return posts;
}
Home.dart
class Home extends GetView<HomeController> {
const Home({super.key});
@override
Widget build(BuildContext context) {
List<Widget> widgets = [
Obx(() => slider()), //**Slider works with Obx very well**
...post(context), /***My problem starts here. I need to
wrap it with Obx to listen to the contents of the list.
I can wrap the slider widget, but I can't wrap the post.
This is required for lazyloading in Listview.
Otherwise, all the elements are loaded without going down.***/
];
return Obx(() {
if (controller.posts.isEmpty) {
return loadHelper(context, controller.netStatus.value, () {
controller.getCategory();
});
} else {
return RefreshIndicator(
edgeOffset: MediaQuery.of(context).padding.top,
onRefresh: () => controller.onRefresh(),
child: Obx(
() => ListView.builder(
shrinkWrap: true,
controller: controller.scrollController,
itemCount: widgets.length + 1,
itemBuilder: (context, index) {
if (index < widgets.length) {
return Obx(() => widgets[index]);
} else {
return loadHelper(context, controller.netStatus.value, () {
controller.getSlide();
});
}
},
),
));
}
});
}
}
Please help me solve the problem. Thank you all.
答案1
得分: 1
尝试将小部件列表的创建移到Obx内部,就像这样:
class Home extends GetView<HomeController> {
const Home({super.key});
@override
Widget build(BuildContext context) {
return Obx(() {
List<Widget> widgets = [
Obx(() => slider()),
...post(context)
];
if (controller.posts.isEmpty) {
return loadHelper(context, controller.netStatus.value, () {
controller.getCategory();
});
} else {
return RefreshIndicator(
edgeOffset: MediaQuery.of(context).padding.top,
onRefresh: () => controller.onRefresh(),
child: Obx(
() => ListView.builder(
shrinkWrap: true,
controller: controller.scrollController,
itemCount: widgets.length + 1,
itemBuilder: (context, index) {
if (index < widgets.length) {
return Obx(() => widgets[index]);
} else {
return loadHelper(context, controller.netStatus.value, () {
controller.getSlide();
});
}
},
),
));
}
});
}
}
我相信这应该解决了您的问题。
英文:
Try moving the creation of the widget list to inside the Obx, so like
class Home extends GetView<HomeController> {
const Home({super.key});
@override
Widget build(BuildContext context) {
return Obx(() {
List<Widget> widgets = [
Obx(() => slider()),
...post(context)
];
if (controller.posts.isEmpty) {
return loadHelper(context, controller.netStatus.value, () {
controller.getCategory();
});
} else {
return RefreshIndicator(
edgeOffset: MediaQuery.of(context).padding.top,
onRefresh: () => controller.onRefresh(),
child: Obx(
() => ListView.builder(
shrinkWrap: true,
controller: controller.scrollController,
itemCount: widgets.length + 1,
itemBuilder: (context, index) {
if (index < widgets.length) {
return Obx(() => widgets[index]);
} else {
return loadHelper(context, controller.netStatus.value, () {
controller.getSlide();
});
}
},
),
));
}
});
}
}
I believe that should solve your issue
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论