【问题标题】:Flutter: Refreshing ListView.Builder with GetXFlutter:使用 GetX 刷新 ListView.Builder
【发布时间】:2021-04-16 20:26:52
【问题描述】:

我正在根据 toDoId 的数量创建List of Cards

toDoController.toDo() 就像

toDo = [q1, r4, g4, d4].obs;

而且,这是我的 ListView.builder()

  Obx(() {
         List _todo = toDoController.toDo();

         return ListView.builder(
         shrinkWrap: true,
         scrollDirection: Axis.horizontal,
         itemCount: _todo.length,
         itemBuilder: (BuildContext context, int i) {
                           
         var _loading = true;
         var _title = 'loading';
                          
         getTodoInfo() async {
         _title = await toDoController
                .getTodoInfo(
                     _todo[i]
                 );
         _loading = false;
         print(_title); // 'Clean!' <--- returns correct title
         }

         getTodoInfo();

         return Container(
           height: 150,
           width: 150,
           child: _loading
           ? Text(
             _title,
             )
             : Text(
             _title,
             ),
     );
    },
   );
  })

我正在尝试让每个 Container 调用 http requests 以从我的数据库中获取标题。获取标题,然后更新到下面的Text() 小部件。但是,从服务器返回值后,它不会更新。

我可以使用FutureBuilder 让他们等待获取标题的请求。我也尝试过 FutureBuilder。但是,FutureBuilder 对variable 的更改也没有反应。所以,我想在这里做到这一点。我有点明白这个问题。之后,小部件返回,它是不可更改的?有什么方法可以用 GetX 做到吗?

【问题讨论】:

    标签: flutter flutter-getx


    【解决方案1】:

    这是一个将 GetX 与 Listview.builder 结合使用的示例。

    此示例使用 GetBuilder 而不是 Obx,因为我不确定使用流是否会带来任何好处。如果由于某种原因需要可观察/流,numbers 可以更新为.obs,并且应该删除update() 调用,并将GetBuilder 替换为GetXObx。如果有人问,我会添加它作为替代示例。

    GetBuilder 包装了 ListView.builder,只有 ListView 会被重建,而不是整个小部件树/页面。

    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    class ListDataX extends GetxController {
      List<int> numbers = List<int>.from([0,1,2,3]);
    
      void httpCall() async {
        await Future.delayed(Duration(seconds: 1), 
                () => numbers.add(numbers.last + 1)
        );
        update();
      }
    
      void reset() {
        numbers = numbers.sublist(0, 3);
        update();
      }
    }
    
    class GetXListviewPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        ListDataX dx = Get.put(ListDataX());
        print('Page ** rebuilt');
        return Scaffold(
          body: SafeArea(
            child: Column(
              children: [
                Expanded(
                  flex: 8,
                  child: GetBuilder<ListDataX>(
                    builder: (_dx) => ListView.builder(
                        itemCount: _dx.numbers.length,
                        itemBuilder: (context, index) {
                          return ListTile(
                            title: Text('Number: ${_dx.numbers[index]}'),
                          );
                        }),
                  ),
                ),
                Expanded(
                  flex: 1,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        RaisedButton(
                          child: Text('Http Request'),
                          onPressed: dx.httpCall,
                        ),
                        RaisedButton(
                          child: Text('Reset'),
                          onPressed: dx.reset,
                        )
                      ],
                    )
                )
              ],
            ),
          ),
        );
      }
    }
    

    Obx/流版本

    这是使用Rx 流和Obx 小部件的上述解决方案。

    class ListDataX2 extends GetxController {
      RxList<int> numbers = List<int>.from([0,1,2,3]).obs;
    
      void httpCall() async {
        await Future.delayed(Duration(seconds: 1),
                () => numbers.add(numbers.last + 1)
        );
        //update();
      }
    
      void reset() {
        numbers = numbers.sublist(0, 3);
        //update();
      }
    }
    
    
    class GetXListviewPage2 extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        ListDataX2 dx = Get.put(ListDataX2());
        print('Page ** rebuilt');
        return Scaffold(
          body: SafeArea(
            child: Column(
              children: [
                Expanded(
                  flex: 8,
                  child: Obx(
                    () => ListView.builder(
                        itemCount: dx.numbers.length,
                        itemBuilder: (context, index) {
                          return ListTile(
                            title: Text('Number: ${dx.numbers[index]}'),
                          );
                        }),
                  ),
                ),
                Expanded(
                    flex: 1,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        RaisedButton(
                          child: Text('Http Request'),
                          onPressed: dx.httpCall,
                        ),
                        RaisedButton(
                          child: Text('Reset'),
                          onPressed: dx.reset,
                        )
                      ],
                    )
                )
              ],
            ),
          ),
        );
      }
    }
    

    【讨论】:

    • 我正在练习使用 Getx 创建列表。想要与服务器交互并在创建或删除时应用 Flutter 动画!太感谢了。我会去看看这个
    • 感谢这个很好的例子。
    • 您好,感谢GetBuilder 解决方案,您能添加numbersObx 替代解决方案吗?我想知道区别,我目前正在使用这种方式,但它似乎不起作用。 TIA!
    • @Zennichimaro 刚刚添加了上面的Obx / Rx 版本。
    • @Zennichimaro 我看了你的问题。我不知道为什么它不为你重建。但我也不熟悉GetWidget 以及它应该如何使用。
    【解决方案2】:

    由于我没有完整的样本,我没有对其进行测试,但我认为这就是您要寻找的:

    FutureBuilder<String>(
      future: toDoController.getTodoInfo(_todo[i]), 
      builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
        if (snapshot.hasData) {
          return Container(
            height: 150,
            width: 150,
            child: Text(snapshot.data),
         );
        } else if (snapshot.hasError) {
          return Text('Error');
        } else {
          return CircularProgressIndicator();
        }
      },
    ),
    

    这是您需要为列表构建器的每个项目返回的代码。

    【讨论】:

    • 哦,我以前也这样做过。当我试图通过单击删除Todo Container() 而不重新渲染时,我被卡住了。当它被添加或删除到列表时,我想有动画效果。有什么办法可以用FutureBuilder 做到这一点?
    猜你喜欢
    • 2021-01-22
    • 2022-10-23
    • 2020-06-08
    • 1970-01-01
    • 2021-12-21
    • 2021-09-08
    • 2021-09-15
    • 2022-08-04
    • 2021-01-13
    相关资源
    最近更新 更多