【问题标题】:Can not use arguments in a stateful widget不能在有状态小部件中使用参数
【发布时间】:2021-04-03 18:18:28
【问题描述】:

我是 Flutter 的初学者,我有一个 api,我使用 Navigator 将数据传递给这个 Route,它工作正常,但只有当我在 build 方法中调用参数时,在 build 方法之外,它们无法被识别,我的目标是在构建方法之外使用我的参数,以便能够创建一个使用 id 参数的 api 调用。问题出在 getClubs 方法和 InitState 方法中

这是我尝试过的

   import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'club_arguments.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';


class ClubDetails extends StatefulWidget {

   final int id;
   final String name;
   final String image;
   final String rank;
   final String nationality;
   final String stadium;
   final  String manager;
   final String wins;
   final String draws;
   final String losses;
   final int goals;
   final int goalsIn;


   ClubDetails({ this.id, this.name,this.image,this.rank,this.nationality,this.stadium,this.manager,this.wins,this.draws,this.losses,this.goals,this.goalsIn});

  @override
  _ClubDetailsState createState() => _ClubDetailsState();
}

class _ClubDetailsState extends State<ClubDetails> {

  String stadium;
  String founded;


  getClub(int id) async {

    http.Response response = await http.get(
        'http://api.football-data.org/v2/teams/$id',
        headers: {'X-Auth-Token': '86014f6025ae430dba078acc94bb2647'});
    String body = response.body;
    Map data = jsonDecode(body);
    stadium = data['name'];

    //Club(this.id,this.name,this.image,this.rank,this.nationality,this.stadium,this.manager,this.wins,this.draws,this.losses,this.goals,this.goalsIn);
    setState(() {
      //print(data[0]['venue']);
      print(stadium);
    });
  }


  @override
  void initState() {
    super.initState();
    getClub(widget.id);
    print(widget.id);
  }
  @override
  Widget build(BuildContext context) {

    List<Titles> titles = [
      Titles("LA LIGA", "Spain","Barcelona","2008" ),
    ];


    
    return Scaffold(
      appBar: AppBar(
        title: Text("Club Info"),
        backgroundColor: Colors.blue[300],
        elevation: 0.0,
      ),
      body: Container(
          decoration: BoxDecoration(
              gradient: LinearGradient(
                  begin: Alignment.centerLeft,
                  end: Alignment.centerRight,
                  colors: [Colors.purple, Colors.blue])
          ),
          child: Container(
            decoration: BoxDecoration(
                gradient: LinearGradient(
                    begin: Alignment.topLeft,
                    end: Alignment.bottomRight,
                    colors: [Colors.purple, Colors.black38])),
            child: ListView(
              children: [
                SizedBox(
                  height: 20,
                ),
                Container(
                  width: double.infinity,
                  child:    Card(
                    elevation: 4.0,
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10.0),
                    ),
                    child: Padding(
                      padding: const EdgeInsets.all(16.0),
                      child:
                      Row(
                        children: <Widget>[
                          Container(
                            height: 40,
                            width: 40,
                            child:
                            SvgPicture.network(widget.image,
                            ),
                          ),
                          const SizedBox(width:10.0),
                          Spacer(),
                          Column(
                            crossAxisAlignment: CrossAxisAlignment.end,
                            children: <Widget> [
                              Text(widget.name, style: TextStyle( fontWeight:FontWeight.bold,
                                fontSize: 18.0,
                              )),
                              const SizedBox(height: 5.0, ),
                              Text("rank : "+widget.rank, style: TextStyle( fontWeight:FontWeight.bold,
                                fontSize: 18.0,
                              )),
                              const SizedBox(height: 5.0, ),
                              Text("Found : "+widget.manager, style: TextStyle( fontWeight:FontWeight.bold,
                                fontSize: 18.0,
                              )),
                              const SizedBox(height: 5.0, ),
                              Text("Nationality : "+widget.nationality, style: TextStyle( fontWeight:FontWeight.bold,
                                fontSize: 18.0, color: Colors.grey[600],
                              )),
                              const SizedBox(height: 5.0, ),
                              Text("Stadium : "+widget.stadium, style: TextStyle( fontWeight:FontWeight.bold,
                                fontSize: 18.0, color: Colors.grey[600],
                              )),
                            ],
                          ),
                        ],
                      ),
                    ),
                  ),
                ),

                SizedBox(
                  height: 10,
                ),
                Container(
                  margin: EdgeInsets.fromLTRB(10, 0, 0, 10),
                  child:  Text(
                    "Achieved Titles",
                    style: TextStyle(fontSize: 17, fontWeight: FontWeight.w900, color: Colors.white),
                  ),
                ),

                SizedBox(
                  height: 10,
                ),
                Container(
                  margin: EdgeInsets.fromLTRB(5, 0, 5, 0),
                  child: ListView.builder(
                    shrinkWrap: true,
                    physics : NeverScrollableScrollPhysics(),
                    itemBuilder: (context, index){
                      return Card(
                        elevation: 4.0,
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(10.0),
                        ),
                        child: Padding(
                          padding: const EdgeInsets.all(16.0),
                          child:
                          Row(
                            children: <Widget>[
                              CircleAvatar(
                                backgroundImage: NetworkImage("https://www.impacttrophies.co.uk/content/images/thumbs/0065685_tower-football-trophy-gold.jpeg"),
                              ),
                              const SizedBox(width:10.0),
                              Spacer(),
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.end,
                                children: <Widget> [
                                  Text(titles[index].name, style: TextStyle( fontWeight:FontWeight.bold,
                                    fontSize: 18.0,
                                  )),
                                  const SizedBox(height: 5.0, ),
                                  Text("country : "+titles[index].country, style: TextStyle( fontWeight:FontWeight.bold,
                                    fontSize: 18.0, color: Colors.grey[600],
                                  )),
                                  const SizedBox(height: 5.0, ),
                                  Text("club : "+titles[index].club, style: TextStyle( fontWeight:FontWeight.bold,
                                    fontSize: 18.0, color: Colors.grey[600],
                                  )),
                                  const SizedBox(height: 5.0, ),
                                  Text("year : "+titles[index].year, style: TextStyle( fontWeight:FontWeight.bold,
                                    fontSize: 18.0, color: Colors.grey[600],
                                  )),
                                ],
                              ),

                            ],
                          ),
                        ),
                      );
                    },
                    itemCount: titles.length,
                  ),
                ),
                SizedBox(
                  height: 70,
                ),
              ],
            ),

          )
      ),
    );
  }
}


class Stats{

  String title;
  String result;

  Stats(this.title,this.result);

}

class Team {

  String name;
  String image;
  String date;

  Team(this.name,this.image,this.date);

}


class Titles {
  String name;
  String country;
  String club;
  String year;

  Titles(this.name,this.country,this.club,this.year);

}

class Club {

  int id;
  String name;
  String image;
  String rank;
  String nationality;
  String stadium;
  String manager;
  String wins;
  String draws;
  String losses;
  int goals;
  int goalsIn;


  Club(this.id, this.name, this.image, this.rank, this.nationality,
      this.stadium, this.manager, this.wins, this.draws, this.losses,
      this.goals, this.goalsIn);

}

我的目标是使用我的参数 id 作为参数调用我的方法 getClub,并使用我从请求 url 中的先前路由收到的 id 参数

【问题讨论】:

  • 请分享您收到的错误。
  • 错误是我在控制台中发现我的 json 值为 null,除了 id 值,当我在 initState 中使用 print 时,后端的所有值都是 null
  • 我在使用查询结果时发现了这个错误:======== 小部件库捕获的异常================= ===================================== 在构建 ClubDetails(dirty, state: _ClubDetailsS​​tate) 时抛出以下 ArgumentError #fc3e7): Invalid argument(s) 相关的导致错误的小部件是:ClubDetails file:///C:/Users/Fares/AndroidStudioProjects/tl_fantasy/lib/clubs/club_navigation_bar.dart:33:42 抛出异常时,这是堆栈:#0 _StringBase.+ (dart:core-patch/string_patch.dart:267:57) ....
  • 我会说你的后端有问题。使用 Postman 之类的其他工具对其进行测试。

标签: flutter dart


【解决方案1】:

您必须将参数传递给您的小部件类,然后在您的状态类中使用它,如下所示:

    class ClubDetails extends StatefulWidget {
       final int id ;

       ClubDetails({this.id});

      @override
      _ClubDetailsState createState() => _ClubDetailsState();
    }

然后您可以像这样使用 widget 在您的状态类 (_ClubDetailsState) 中使用它。

  @override
  void initState() {
    super.initState();
    getClub(widget.id);
  }

您不再需要在状态类 (_ClubDetailsState) 中创建 id 变量

现在,您可以在构建小部件时轻松地将 id 值作为参数传递给小部件,如下所示:

ClubDetails(id : 1);

【讨论】:

  • 我已经将一个对象传递给我的类,查看构建方法,你会发现参数变量,这就是我传递的所有内容
【解决方案2】:

您需要做的就是在Stateful Widget 中声明变量并在构造函数中设置它们。然后在State Widget 上,使用widget. 前缀访问它们,如下所示:

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Issue66934490(name: 'name');
  }
}

class Issue66934490 extends StatefulWidget {
  final String name;
  
  Issue66934490({
    this.name,
  });
  
  @override
  _Issue66934490State createState() => _Issue66934490State();
}

class _Issue66934490State extends State<Issue66934490> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(widget.name),
    );
  }
}

【讨论】:

  • 我还是有问题@override void initState() { super.initState(); getClub(widget.id);打印(小部件.id);这里 widget.id 是 null ,你能告诉我为什么吗?我会更新我的代码
  • 您没有向我们展示您在哪里调用 ClubDetails 小部件类。你确定你没有传递null id?
  • 好的,现在我将 id 添加到 ClubDetails 小部件,它不为空,但我的问题是我想要获取的 json 值,当我尝试在 initState 方法中打印它们时,我发现他们为空
猜你喜欢
  • 2021-12-15
  • 2021-10-29
  • 2020-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-20
  • 2020-11-05
  • 2021-05-23
相关资源
最近更新 更多