setState未更新UI

问题描述 投票:0回答:3

我正在尝试从API提取数据,并且能够获取日志,但setState无法正常工作。总的来说,我想要实现的是是否有响应在屏幕上显示数据,API或服务器上是否有错误或我想在小吃栏中显示任何其他内容。我的moto也要显示错误。

下面是我的模特班

import 'http.dart';

class User {
int userId;
int id;
String title;
String body;

User({this.userId, this.id, this.title, this.body});

User.fromJson(Map<String, dynamic> json) {
  userId = json['userId'];
  id = json['id'];
  title = json['title'];
  body = json['body'];
}

Map<String, dynamic> toJson() {
  final Map<String, dynamic> data = new Map<String, dynamic>();
  data['userId'] = this.userId;
  data['id'] = this.id;
  data['title'] = this.title;
  data['body'] = this.body;
  return data;
}


}


class UserExt {

static getUserInfo(Function(User user) success, Function(String errorMesssage) error) async{

  final response = await HTTP.get(api: "https://jsonplaceholder.typicode.com/posts/1");
  if(response.isSuccess == true) {
    success(User.fromJson(response.response));
  } else {
    error(response.response);
  }

}

}

下面是我的http.dart文件

import 'dart:html';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
import 'dart:convert' as convert;
import 'package:http/http.dart';

const _timeoutDuration = Duration(seconds: 5);

class HTTP {


  static Future<HttpResponse> get({@required String api}) async {

    try {
      Response response = await http.get(api).timeout(_timeoutDuration);
      return _modeledResponse(response);
    } catch (error) {
      return HttpResponse(isSuccess: false, response: error.toString());
    }


  }

  static Future<HttpResponse> _modeledResponse(Response response) async {

    try {
      if(response.statusCode == HttpStatus.ok) {
        var jsonResponse = convert.jsonDecode(response.body);
        return HttpResponse(isSuccess: true, response: jsonResponse);
      } else {
        return HttpResponse(isSuccess: false, response: response.statusCode.toString());
      }
    } catch (error) {
      return HttpResponse(isSuccess: false, response: error.toString());
    }

  }



}




class HttpResponse {
  final bool isSuccess;
  final dynamic response;
  HttpResponse({@required this.isSuccess, @required this.response});
}

下面是我调用API的屏幕。

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http_request/User.dart';
import 'http.dart';






class ApiCalling extends StatefulWidget {
  @override
  _ApiCallingState createState() => _ApiCallingState();
}

class _ApiCallingState extends State<ApiCalling> {

  bool showLoader = false;

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      body: Center(
        child: Stack(
          children: <Widget>[


            Center(
              child: RaisedButton(
                child: Text("Call API"),
                onPressed: () {

                  setState(() {
                    showLoader = true;
                  });
                  UserExt.getUserInfo((user){
                    print("UUUser id = ${user.userId}");
                    Scaffold.of(context).showSnackBar(SnackBar(content:     Text("${user.userId}"),));

                setState(() {
                  showLoader = false;
                });


              }, (error){
                Scaffold.of(context).showSnackBar(SnackBar(content: Text("${error}"),));
                setState(() {
                  showLoader = false;
                });
              });


            },
          ),
        ),
        Visibility(child: CircularProgressIndicator(backgroundColor: Colors.pink,), visible: showLoader,),


      ],
    ),
  ),
);
  }
}

在当前代码中指示器未显示/隐藏或小吃栏也未显示。

flutter dart flutter-layout
3个回答
2
投票

从颤振https://api.flutter.dev/flutter/material/Scaffold/of.html的官方文档中>

当在同一构建函数中实际创建了脚手架时,该构建函数的context参数不能用于找到该脚手架(因为它在窗口小部件树中返回的窗口小部件“上方”)。在这种情况下,可以使用以下带有Builder的技术来为BuildContext提供“在”脚手架下方的新作用域:

所以基本上问题出在您的脚手架上下文

,所以不要使用实例化脚手架的直接父级上下文,而应使用子级上下文。

下面的代码将起作用。

class _ApiCallingState extends State<ApiCalling> {
  bool showLoader = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Builder(
        builder: (context)=>
            Center(
        child: Stack(
          children: <Widget>[
            Center(
              child: RaisedButton(
                child: Text("Call API"),
                onPressed: () {
                  setState(() {
                    showLoader = true;
                  });
                  UserExt.getUserInfo((user) {
                    print("UUUser id = ${user.userId}");
                    print("context==$context");
                    Scaffold.of(context).showSnackBar(SnackBar(
                      content: Text(" User Id${user.userId}"),
                    ));
                     setState(() {
                      showLoader = false;

                    });



                  }, (error) {
                    setState(() {
                      showLoader = false;
                    });
                    Scaffold.of(context).showSnackBar(SnackBar(
                      content: Text("${error}"),
                    ));

                  });
                },
              ),
            ),
            Visibility(
              child:
              Center(
                child:CircularProgressIndicator(
                  backgroundColor: Colors.pink,
                ),

              ),
              visible: showLoader,
            )
          ],
        ),
      ),
      )

    );
  }
}

1
投票

只需进行以下更改和加载项,只需检查以下代码即可:


-3
投票

声明全局密钥final _scaffoldKey = GlobalKey();

© www.soinside.com 2019 - 2024. All rights reserved.