【问题标题】:only static members can be accessed in initializers在初始化器中只能访问静态成员
【发布时间】:2019-07-05 12:13:21
【问题描述】:

我有一个 int 值从第一个屏幕传递到第二个屏幕,我可以毫无问题地获得我的值...我的问题是我想将收到的值添加到 astring 以完成并开始使用我的 api这需要添加第一个屏幕的导入值...我被困在我无法将其更改为静态的接收到的 int 和需要添加的值是静态的 api 字符串之间

第二屏:

   class CatsNews extends StatefulWidget {

    @override
    _CatsNewsState createState() => new _CatsNewsState();

    }

    class _CatsNewsState extends State<CatsNews> {
    int _id ;
    String root = "http://api.0mr.net";
    String  url = "/api/GetCategoryById/$_id";
    @override

    List data;

    Future<String> getDrawerItem() async {
    var response = await http.get(
    Uri.encodeFull(url), headers: {"Accept": "application/json"});
    setState(() {
    var respondbody = json.decode(response.body);
    data = respondbody["StoriesCategory"];
    });
    }

    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(
    title: Text('Cat Screen'),
    ),
    body:  Center()

我通过共享首选项获取值,如果它在 Widget build(BuildContext context) 中,它可以正常工作

   @override
    void initState() {
    getIntPrefrence().then(updatId);
    super.initState();
    this.getDrawerItem();
    }

    void updatId(int id) {
    setState(() {
    this._id = id;
    });
    }
    }

更新: 我已将 Srting url 添加到 initstate() 中,代码如下:

    class _CatsNewsState extends State<CatsNews> {
    @override
    List data;
    int _id  ;
    var response;
    String root = "http://-api.0mr.net";
    String url ;


    Future<String> getDrawerItem() async {
    response = await http
    .get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
    setState(() {
    var respondbody = json.decode(response.body);
    data = respondbody["StoriesCategory"];
    });
    }

    Widget build(BuildContext context) {

    return Scaffold(
    appBar: AppBar(
    title: Text('$_id'),
    ),
    body: Center()

    }


    Future<int> getIntPrefrence() async {
    SharedPreferences pref = await SharedPreferences.getInstance();
    int id = pref.getInt("id");
    return id;
    }

    @override
    void initState() {
    super.initState();
    getIntPrefrence().then(updatId);
    updateurl();
    this.getDrawerItem();

    //initResponse();


    }

    updateurl() {
    setState(() {
    this.url= "$root/api/CategoryId/$_id";

    });
    }

    void updatId(int id) {
    setState(() {
    this._id = id;
    });
    }


    }

之前的问题是通过将字符串添加到 initstate() 来解决的,但是更新的值不会添加到字符串中,并且会将导入的 int id 处理为 null 或零,但是 int id 可以正常工作并显示导入的Widget build(BuildContext context) 内任何小部件中的值

【问题讨论】:

  • initState中设置网址

标签: dart flutter


【解决方案1】:

有问题的代码可能是

var response = await http.get(...

你不能在上面代码中=之后的部分的字段初始化器中有任意代码。

Dart 在对象创建步骤中具有严格的顺序。 字段初始化器在构造函数初始化列表之前和超类的构造函数初始化列表之前执行。

只有在所有超类的所有构造函数初始化列表都执行完毕后,构造函数体才被执行,然后才允许访问this,你的类的实例正在被创建。

您的代码在此之前(隐式)访问this,此时对象初始化尚未完成,因此禁止访问this 以防止未定义的行为。

静态成员可以安全访问,因为它们不依赖于对象初始化。它们完全可以在没有实例的情况下使用。

错误消息告诉您的是,您的初始化程序正在尝试执行目前无法执行的操作,您需要将代码移至其他位置。

字段初始化代码可以移到构造函数初始化列表中。如果字段应该是final,通常会这样做, 或构造函数体,或方法 - 如下所示。

var response;
@override
void initState() {
  super.initState();
  _initResponse();
}

void _initResponse() async {
  response = await http.get(
    Uri.encodeFull(url), headers: {"Accept": "application/json"});
    setState(() {
    var respondbody = json.decode(response.body);
    data = respondbody["StoriesCategory"];
  });
}

因为initState 不允许async,我们将代码移动到另一个我们从initState 调用的方法(_initResponse)。

【讨论】:

  • 我的问题根本不在于响应,如果我在字符串中放入一个有效的 api,它可以正常工作...我的问题是当我尝试将导入的值添加到退出的字符串时作为“ String url = "/api/GetCategoryById/$_id" " 这里出现提到的消息...我希望能够将导入的值添加到字符串以开始我的请求..我已将字符串添加到 init状态并且消息现在已经消失了,但是从第一个屏幕导入的值不适用于 String ant,当它在 Widget build 内的任何小部件中正常工作时,请求将其处理为 null 或零
  • 我在您的问题中看不到该代码。如果没有更具体的信息,很难知道究竟是什么代码导致了您的错误。我只是猜测可能导致问题的代码。
  • String url = "/api/GetCategoryById/$_id";....这一行的问题,因为我无法将 id 的值添加到字符串 url...现在可以使用在将字符串 url 添加到 initState() 之后,但前提是手动为 int id 设置一个值,例如 int id =5;在这里它将获得值为 5 的 api,但仍然如此,但是从第一个屏幕导入的值是什么..我应该怎么做才能解决这个问题?...提前谢谢
  • 抱歉,我不明白是什么问题。关于如何从一个文件到另一个文件或从一个类到另一个类的值有几十个问题的答案。请尝试查找它们。听起来这就是你想要做的。
  • 经过大量搜索和尝试后,问题现已解决...我在 getDrawerItem() 函数中更改了变量和共享首选项值,它解决了问题...您的建议有帮助我非常非常感谢:)
【解决方案2】:

我的问题的解决方案是在方法中添加导入的值和我想根据它编辑的字符串,该方法将启动我的 api 请求,如下所示:

    void initState() {
    super.initState();
    this.getDrawerItem();
    }

    Future<String> getDrawerItem() async {
    int _id ;
    String url;
    SharedPreferences pref = await
    SharedPreferences.getInstance();
    _id = (pref.getInt("id")?? 0);
    url = "http://gomhuriaonline-api.0mr."
        "net/api/GetCategoryById/$_id";
    print(url);
    response = await http
    .get(Uri.encodeFull(url), headers: 
    {"Accept": "application/json"});
    setState(() {
    var respondbody = json.decode(response.body);
    data = respondbody["StoriesCategory"];
    });
    }
    }

【讨论】:

    猜你喜欢
    • 2020-08-05
    • 1970-01-01
    • 2020-01-05
    • 2019-01-23
    • 2018-11-13
    • 1970-01-01
    • 2020-08-31
    • 2020-02-09
    相关资源
    最近更新 更多