Flutter Getx。在Obx中监听列表出错。如何修复?

huangapple go评论140阅读模式
英文:

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&lt;Category&gt; category = &lt;Category&gt;[].obs;
  final RxList&lt;Post&gt; slide = &lt;Post&gt;[].obs;
  final RxList&lt;Post&gt; posts = &lt;Post&gt;[].obs;

Future&lt;void&gt; getPost() async {
    await Service().getPost(start.value, limit).then((value) {
      if (value.isNotEmpty) {
        if (value.length &lt; 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&lt;Widget&gt; post(BuildContext context) {
  final CacheManager cacheManager = CacheService().cacheManager;
  HomeController controller = Get.find&lt;HomeController&gt;();

  List&lt;Widget&gt; posts = [
    ...controller.posts.map((post) =&gt; postCard(
          context,
          post,
          controller.category[int.parse(post.categoryId!) - 1],
          cacheManager,
        )),
  ];

  return posts;
}

Home.dart

class Home extends GetView&lt;HomeController&gt; {
  const Home({super.key});

  @override
  Widget build(BuildContext context) {
    List&lt;Widget&gt; widgets = [
      Obx(() =&gt; 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&#39;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: () =&gt; controller.onRefresh(),
            child: Obx(
              () =&gt; ListView.builder(
                shrinkWrap: true,
                controller: controller.scrollController,
                itemCount: widgets.length + 1,
                itemBuilder: (context, index) {
                  if (index &lt; widgets.length) {
                    return Obx(() =&gt; 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&lt;HomeController&gt; {
  const Home({super.key});

  @override
  Widget build(BuildContext context) {
    return Obx(() {
      List&lt;Widget&gt; widgets = [
        Obx(() =&gt; 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: () =&gt; controller.onRefresh(),
            child: Obx(
              () =&gt; ListView.builder(
                shrinkWrap: true,
                controller: controller.scrollController,
                itemCount: widgets.length + 1,
                itemBuilder: (context, index) {
                  if (index &lt; widgets.length) {
                    return Obx(() =&gt; widgets[index]);
                  } else {
                    return loadHelper(context, controller.netStatus.value, () {
                      controller.getSlide();
                    });
                  }
                },
              ),
            ));
      }
    });
  }
}

I believe that should solve your issue

huangapple
  • 本文由 发表于 2023年6月19日 16:53:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76505078.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定