【问题标题】:Flutter GetX Timer Error. HomePage is not refreshedFlutter GetX 计时器错误。主页未刷新
【发布时间】:2021-09-08 07:21:45
【问题描述】:

我正在尝试每 30 秒获取一次数据,但我不知道该怎么做。我创建的 Getx 控制器文件没有问题。我可以提取数据,但它不刷新。

这是我的控制器:

class AllCoinController extends GetxController {
  var coinList = [].obs;
  var coinCounter = 0.obs;

 Future callAllCoins() async {
    try {
      final response = await http.get(url);

      if (response.statusCode == 200) {
        List<dynamic> values = [];
        values = allCoinsFromJson(response.body);
        coinCounter.value = values.length;

        if (values.length > 0) {
          for (int i = 0; i < values.length; i++) {
            if (values[i] != null) {
              coinList.add(values[i]);
            }
          }
        }
        return coinList;
      } else {
        print(response.statusCode);
      }
    } catch (e) {
      print(e.toString());
    }
  }

  @override
  void onInit() {
    callAllCoins();
    Timer.periodic(Duration(seconds: 30), (timer) => callAllCoins());
    super.onInit();
  }
}

还有我的主页:

    class HomePage extends StatelessWidget {
  final AllCoinController allCoinController = Get.put(AllCoinController());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Obx(
        () => ListView.builder(
          scrollDirection: Axis.vertical,
          itemCount: allCoinController.coinCounter.value,
          itemBuilder: (context, index) {
            return Container(
              width: 150,
              child: Row(
                children: [
                  SizedBox(
                    width: 50,
                    height: 50,
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Image.network(
                          allCoinController.coinList[index].image),
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(allCoinController.coinList[index].name),
                  ),
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(allCoinController.coinList[index].symbol),
                  ),
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Obx(
                      () => Text(allCoinController.coinList[index].currentPrice
                          .toString()),
                    ),
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );
  }
}

代码没有问题,唯一的问题是计时器不工作。

【问题讨论】:

    标签: flutter dart flutter-getx


    【解决方案1】:

    您发布的代码每 30 秒将新值添加到列表中,但计数不会增加。为了显示这些新值,您要么必须根据 nem 项目的数量增加计数,要么替换列表中的现有值(在添加之前将其清空)

    另外,请注意以下代码在初始化时调用了 callAllCoins() 两次。

    @override
      void onInit() {
        callAllCoins(); // This should be removed
        Timer.periodic(Duration(seconds: 30), (timer) => callAllCoins()); // This is called right in this line, then every 30 sec.
        super.onInit();
      }
    

    我在下面为您提供一个关于我的想法的基本示例。

    import 'dart:async';
    
    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      final controller = Get.put(MyAppController());
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Container(
            child: Obx(() {
              print(controller.counter);
              return ListView.builder(
                itemBuilder: (context, index) => Text(controller.list[index]),
                itemCount: controller.counter.value,
              );
            }),
          ),
        );
      }
    }
    
    class MyAppController extends GetxController {
      var list = [].obs;
      var counter = 0.obs;
    
      callIncrement() {
        list.add('->');
        counter.value += 1;
      }
    
      @override
      void onInit() {
        Timer.periodic(Duration(seconds: 1), (_) => callIncrement());
        super.onInit();
      }
    }
    
    

    【讨论】:

    • 非常感谢您的回答。我刚开始使用 Getx。我不明白该怎么做。当我在不使用 getx 的情况下这样做时,计时器工作正常。你认为我应该使用状态管理吗?
    • 你的问题并不是关于 GetX 或 Flutter。取而代之的是一些算法思维。继续努力,你会在这些方面有所改进 :) 我真的很喜欢 GetX,它是一个高级状态管理库等等。
    • medium.com/flutter-community/…我向你推荐这篇文章,这是我决定用 GetX 做实验时读到的第一篇文章
    • 谢谢你,我当然会阅读,但我的意思是这里的情况不同。示例我添加此代码行:floatingActionButton: FloatingActionButton(child: Icon(Icons.refresh), onPressed: () { allCoinController.callAllCoins(); }, ),但仍然不起作用。因为我使用 stateles 小部件但是,使用 getx 时它不应该工作吗?
    • GetX 为你做所有的事情。我现在只是在猜测,但你应该用 Obx() 包装那个 FAB。此外,考虑使用 GetX(builder: (controller) => WidgetTree()) 格式。使用 GetX 可以得到更清晰的代码。
    【解决方案2】:

    我认为您的控制器有问题。例如,您通过循环手动在列表中添加值。您可以在 REST 调用之后简单地使用 coinList.assignAll(values),而无需编写所有手动代码。 assignAll() 方法提供的好处之一是它通知更改。 因此,您不需要 coinCounter 变量,您只需执行以下操作:

    ... 
    values = allCoinsFromJson(response.body);
    coinList.assignAll(values);
    ...
    

    ListView.builder 上使用itemCount: allCoinController.coinList.length

    【讨论】:

    • 非常感谢它有效,但我有一个问题。 “assignAll”到底是做什么的?例如,我们可以在数据不需要不断更新的应用程序中使用它吗?
    • assignAll 只是将RxList&lt;&gt; 中的现有值替换为新的可迭代值。其中addAll 只是在现有值的末尾附加新的可迭代值。无论是否需要更新数据,您都可以使用assignAllRxList。但是在那种情况下使用 Rx 有点过头了。因为 Rx 的默认行为是通知观察者有任何变化,而不管添加、替换、删除。因此,如果您的数据没有改变,请不要使用 Rx。它有成本。
    • 非常感谢您提供的信息。我想我可以通过使用计时器每 5 分钟获取一次数据来平衡这种情况。
    猜你喜欢
    • 2021-04-16
    • 2022-01-18
    • 2021-05-11
    • 2022-07-23
    • 2021-12-21
    • 1970-01-01
    • 2021-10-03
    • 2021-01-22
    • 2020-04-19
    相关资源
    最近更新 更多