如何在flutter中加载数据之前显示进度对话框?

S. *_*sif 8 loading dart progress-bar flutter dataloader

在我的 Flutter 项目中,我正在执行 API 调用以通过 GET 请求获取数据。从响应解析JSON 对象后,我只在Text小部件中显示值。虽然加载数据需要时间,但同时我的 Text 小部件显示为空。

对于 API 调用部分,我有以下代码-

class Webservice {
  Future<T> load<T>(Resource<T> resource) async {
    var jwt = await LocalStore().getJWT();
    print(jwt);

    final response = await http.get(resource.url,
        headers: {
          'Content-Type': 'application/json',
          'token': '${Constants.TOKEN}',
          'jwt': '$jwt',
        }
    );
    if(response.statusCode == 200) {
      print('${response.body}');
      return resource.parse(response);
    } else {
      throw Exception('Failed to load data!');
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我为 JSON 解析创建了一个Model 类-

class Category {
  int catNote;
  int catTodo;
  int catRem;
  int catTag;
  int catUrgent;
  int catWork;
  int catOffice;
  int catPersonal;
  
  Category(
      {this.catNote,
        this.catTodo,
        this.catRem,
        this.catTag,
        this.catUrgent,
        this.catWork,
        this.catOffice,
        this.catPersonal});

  Category.fromJson(Map<String, dynamic> json) {
    catNote = json['cat_note'];
    catTodo = json['cat_todo'];
    catRem = json['cat_rem'];
    catTag = json['cat_tag'];
    catUrgent = json['cat_urgent'];
    catWork = json['cat_work'];
    catOffice = json['cat_office'];
    catPersonal = json['cat_personal'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['cat_note'] = this.catNote;
    data['cat_todo'] = this.catTodo;
    data['cat_rem'] = this.catRem;
    data['cat_tag'] = this.catTag;
    data['cat_urgent'] = this.catUrgent;
    data['cat_work'] = this.catWork;
    data['cat_office'] = this.catOffice;
    data['cat_personal'] = this.catPersonal;
    return data;
  }

  static Resource<Category> get allCategory {
    return Resource(
        url: '${Constants.BASE_URL}category',
        parse: (response) {
          print('my result ${response.body}');
          final result = json.decode(response.body);

          Category category = Category.fromJson(result) ;
          return category;

        }
    );

  }

}
Run Code Online (Sandbox Code Playgroud)

现在,在我的主类中,我创建了一个函数,如下所示 -

  void _getAllCategories() {
    Webservice().load(Category.allCategory).then((newsArticles) => {
        setState(() => {
      _category = newsArticles
    })
  });
 }
Run Code Online (Sandbox Code Playgroud)

之后,我在 initState 函数中调用了该函数并将值保存在 _category 对象中。

然后在Text 小部件的 Widget build(BuildContext context)函数中,我使用了来自_category对象的值,如下所示,使用三元运算符来检查对象是否为空。如果为空,则应显示 0,如果不为空,则应显示原始值-

child: _category ==null?
                Text('0',
                style: TextStyle(
                    fontSize: 30,
                    fontWeight: FontWeight.bold
                ),
                ):
                Text('${_category.catToDo}',
                  style: TextStyle(
                      fontSize: 30,
                      fontWeight: FontWeight.bold
                  ),
                )
Run Code Online (Sandbox Code Playgroud)

但它仍然显示为空,而数据加载需要几秒钟,并显示如下输出 -

在此处输入图片说明

因此,我需要一个解决方案来显示进度对话框或仅将默认值显示为 0,而数据加载需要时间。如果有人帮助我解决此代码,那就太好了。

Mul*_*dec 10

使用 FutureBuilder 在加载期间控制渲染;

  final categories = Webservice().load(Category.allCategory);

  Widget build(BuildContext context) {
    return FutureBuilder(
      future: categories,
      builder: (ctx, snapshot) {
        var value = (snapshot.connectionState == ConnectionState.done) ? '${_category.catToDo}' : '0';

        return Text(
          value,
          style: TextStyle(
            fontSize: 30,
            fontWeight: FontWeight.bold
          ),
        );
      }
    );
  }
Run Code Online (Sandbox Code Playgroud)

或者,如果您想显示加载动画:

  final categories = Webservice().load(Category.allCategory);

  Widget build(BuildContext context) {
    return FutureBuilder(
      future: categories,
      builder: (ctx, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          return Text(
            '${_category.catToDo}',
            style: TextStyle(
              fontSize: 30,
              fontWeight: FontWeight.bold
            ),
          );
        }
        else {
          return CircularProgressIndicator();
        }
      }
    );
  }
Run Code Online (Sandbox Code Playgroud)


Enz*_*ama 5

您可以检查包以显示不同样式的加载旋转。

之后您需要使用Future Builder小部件

这是如何将其与 spinkit 一起使用的示例

FutureBuilder(
        future: myAwesomeFutureMethod(), // you should put here your method that call your web service
        builder:

            (BuildContext context, AsyncSnapshot<List<BillResponse>> snapshot) { 
            /// The snapshot data type have to be same of the result of your web service method
          if (snapshot.hasData) {
            /// When the result of the future call respond and has data show that data
            return SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              child: bodyData(snapshot.data),
            );
          }
          /// While is no data show this
          return Center(
            child: SpinKitDualRing(
              color: Colors.blue,
            ),
          );
        },
      ),
Run Code Online (Sandbox Code Playgroud)

希望这能有所帮助。干杯。