Flutter/Dart:启动应用程序时如何在第一个选项卡上加载数据?

Mic*_*sma 5 dart flutter

简要说明:我正在创建一个当前具有三个选项卡的应用程序。加载应用程序时,数据不会加载到第一页。它只是说“寻找特价商品”。当我向左滑动时,信息会加载到第二个和第三个选项卡上,只有当我返回到第一个选项卡时,信息才会加载到那里。图片

代码:

void main() => runApp(MaterialApp(
      title: "Local Hour application",
      debugShowCheckedModeBanner: false,
      home: MyTabs(), //Change to HomePage when wanting first clicking page
    )
);

class MyTabs extends StatefulWidget {
  @override
  MyTabsState createState() => MyTabsState();
}

class MyTabsState extends State<MyTabs> with SingleTickerProviderStateMixin {

  final String url = 'url-info-I-can\'t-disclose'; //API url
  List specials;
  TabController controller;

  @override
  void initState() {
    super.initState();

    controller = TabController(vsync: this, length: 3);

    this.getSpecials().then((jsonSpecials) {
      setState(() {
        specials = jsonSpecials;
      });
    });
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  Future<List> getSpecials() async {
    var response = await http.get(
        Uri.encodeFull(url + '/specials'),
        headers: {"Accept": "application/json"});
    return jsonDecode(response.body);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: Icon(Icons.dehaze), //there's an "action" option for menus and stuff. "leading" for show
        title: specials == null ? Text("LOCAL HOUR",) : Text("Now with more special",),
        backgroundColor: Colors.green,
        bottom: TabBar(
          controller: controller,
          tabs: [
            Padding(
              padding: const EdgeInsets.all(15.0),
              child: Text("Today", style: TextStyle(fontSize: 15.0),),
            ),
            Padding(
              padding: const EdgeInsets.all(15.0),
              child: Text("Tomorrow", style: TextStyle(fontSize: 15.0),),
            ),
            Padding(
              padding: const EdgeInsets.all(15.0),
              child: Text("Next Day", style: TextStyle(fontSize: 15.0),),
            ),
          ],
        )
      ),
      body: TabBarView(
        controller: controller,
        children: <Widget>[
          SecondPage(specials: specials),
          SecondPage(specials: specials),
          SecondPage(specials: specials),
        ],
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

**当前问题:** 启动时无法加载第一页。仅在选项卡之间来回切换时。

**我的目标:** 确保在启动应用程序时确实加载了数据,并且我不必为了看到第一页而来回走动。

如果我需要提供更多信息,请告诉我。

Pro*_*Pro 5

Michael,您应该使用FutureBuilder来发出未来的请求,而不是在initState(). 以下是如何实施它。由于我没有你的api,所以我使用了测试api来演示。

class MyTabs extends StatefulWidget {
  @override
  MyTabsState createState() => MyTabsState();
}

class MyTabsState extends State<MyTabs> with SingleTickerProviderStateMixin {
  final String url = 'https://jsonplaceholder.typicode.com/posts'; //API url

  List specials;
  TabController controller;

  @override
  void initState() {
    super.initState();

    controller = TabController(vsync: this, length: 3);

//    this.getSpecials().then((jsonSpecials) {
//      setState(() {
//        specials = jsonSpecials;
//      });
//    });
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  Future<List> getSpecials() async {
    var response = await http.get(Uri.encodeFull(url),
        headers: {"Accept": "application/json"});
    return jsonDecode(response.body);
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: getSpecials(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            print(snapshot.data[0]);
            return MaterialApp(
                home: Scaffold(
              appBar: AppBar(
                  leading: Icon(Icons.dehaze),
                  //there's an "action" option for menus and stuff. "leading" for show
                  title: specials == null
                      ? Text("LOCAL HOUR")
                      : Text("Now with more special"),
                  backgroundColor: Colors.green,
                  bottom: TabBar(
                    controller: controller,
                    tabs: [
                      Padding(
                        padding: const EdgeInsets.all(15.0),
                        child: Text("Today", style: TextStyle(fontSize: 15.0)),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(15.0),
                        child:
                            Text("Tomorrow", style: TextStyle(fontSize: 15.0)),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(15.0),
                        child:
                            Text("Next Day", style: TextStyle(fontSize: 15.0)),
                      ),
                    ],
                  )),
              body: TabBarView(
                controller: controller,
                children: <Widget>[
                  Padding(padding: EdgeInsets.only(top: 10.0),child: Text(snapshot.data[0]["title"], textAlign: TextAlign.center, style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold))),
                  Padding(padding: EdgeInsets.only(top: 10.0),child: Text(snapshot.data[1]["title"], textAlign: TextAlign.center, style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold))),
                  Padding(padding: EdgeInsets.only(top: 10.0),child: Text(snapshot.data[2]["title"], textAlign: TextAlign.center, style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold))),
                ],
              ),
            ));
          } else {
            return Center(child: CircularProgressIndicator());
          }
        });
  }
}
Run Code Online (Sandbox Code Playgroud)

演示