如何从Future中正确返回列表以在Flutter的ListView.Builder中使用?

时间:2020-09-27 23:13:04

标签: flutter

我希望从Future中获取列表,并在ListView.Builder中使用此列表。唯一的问题是,我显然正在寻找一种实现此目标的好方法。如果有人可以给我一些建议,这里有一些代码片段。谢谢!

我在其中调用Data函数以及ListView.Builder

class _ChangeQuarterState extends State<ChangeQuarter> {
  static const Color greycolor = Color.fromRGBO(220, 220, 220, 10);


 Future<List<Quarter>> quarters = getQuarters();


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[200],
      appBar: PreferredSize(
        preferredSize: Size.fromHeight(95.0),
        child: AppBar(
          automaticallyImplyLeading: false, // hides leading widget
          flexibleSpace: QuarterAppBar(),
        ),
      ),
      body: Container(
        child: ListView.builder(
          itemCount: quarters[index],
          shrinkWrap: true,
          itemBuilder: (context, index) {
            return Padding(
              padding: EdgeInsets.symmetric(vertical: 1.0, horizontal: 4.0),
              child: Card(
                color: (index % 2 == 0) ? greycolor : Colors.white,
                child: Container(
                    height: 60,
                    padding: EdgeInsets.fromLTRB(0, 20, 0, 0),
                    child: InkWell(
                      onTap: () => Navigator.pop(context),
                      child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Container(
                          margin: EdgeInsets.only(right: 5),
                          child: Text(quarters[index].quarter,
                              style: TextStyle(
                                  fontSize: 20,
                                  fontFamily: 'Montserrat',
                                  color: BBFILightBlue),
                              textAlign: TextAlign.left),
                        ),

在哪里获取要转换为Builder列表的数据

Future<Quarter> getQuarters() async {
  final http.Response response = await http.get(
    'https://fakedapi.com/getQuarters',
    headers: <String, String>{
      'Authorization': 'topsecret',
    },
  );
  if (response.statusCode <400) {
    return  Quarter.fromJson(json.decode(response.body));


  } else {
    throw Exception('Failed to get quarters');
  }
}

1 个答案:

答案 0 :(得分:1)

您可以在下面复制粘贴运行完整代码
您可以使用FutureBuilder并操作snapshot.data
代码段

Future<List<Quarter>> _future;

@override
  initState() {
    _future = getQuarters();
  }


FutureBuilder(
            future: _future,
            builder: (context, AsyncSnapshot<List<Quarter>> snapshot) {
              switch (snapshot.connectionState) {
                ...
                  } else {
                    return ListView.builder(
                        itemCount: snapshot.data.length,
                        shrinkWrap: true,
                        ...
                                  child: Text(
                                      snapshot
                                          .data[index].quarter,

工作演示

enter image description here

完整代码

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

List<Quarter> quarterFromJson(String str) =>
    List<Quarter>.from(json.decode(str).map((x) => Quarter.fromJson(x)));

String quarterToJson(List<Quarter> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Quarter {
  Quarter({
    this.quarter,
  });

  String quarter;

  factory Quarter.fromJson(Map<String, dynamic> json) => Quarter(
        quarter: json["quarter"],
      );

  Map<String, dynamic> toJson() => {
        "quarter": quarter,
      };
}

class ChangeQuarter extends StatefulWidget {
  @override
  _ChangeQuarterState createState() => _ChangeQuarterState();
}

class _ChangeQuarterState extends State<ChangeQuarter> {
  static const Color greycolor = Color.fromRGBO(220, 220, 220, 10);
  Future<List<Quarter>> _future;

  Future<List<Quarter>> getQuarters() async {
    /*final http.Response response = await http.get(
      'https://fakedapi.com/getQuarters',
      headers: <String, String>{
        'Authorization': 'topsecret',
      },
    );*/
    String jsonString = '''
    [{
    "quarter" : "1"
},
{
    "quarter" : "2"
},
{
    "quarter" : "3"
},
{
    "quarter" : "4"
}
]
    ''';
    final http.Response response = http.Response(jsonString, 200);

    if (response.statusCode < 400) {
      return quarterFromJson(
          response.body); //Quarter.fromJson(json.decode(response.body));

    } else {
      throw Exception('Failed to get quarters');
    }
  }

  @override
  initState() {
    _future = getQuarters();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.grey[200],
        appBar: PreferredSize(
          preferredSize: Size.fromHeight(95.0),
          child: AppBar(
            automaticallyImplyLeading: false, // hides leading widget
            //flexibleSpace: QuarterAppBar(),
          ),
        ),
        body: FutureBuilder(
            future: _future,
            builder: (context, AsyncSnapshot<List<Quarter>> snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.none:
                  return Text('none');
                case ConnectionState.waiting:
                  return Center(child: CircularProgressIndicator());
                case ConnectionState.active:
                  return Text('');
                case ConnectionState.done:
                  if (snapshot.hasError) {
                    return Text(
                      '${snapshot.error}',
                      style: TextStyle(color: Colors.red),
                    );
                  } else {
                    return ListView.builder(
                        itemCount: snapshot.data.length,
                        shrinkWrap: true,
                        itemBuilder: (context, index) {
                          return Padding(
                              padding: EdgeInsets.symmetric(
                                  vertical: 1.0, horizontal: 4.0),
                              child: Card(
                                  color: (index % 2 == 0)
                                      ? greycolor
                                      : Colors.white,
                                  child: Container(
                                      height: 60,
                                      padding: EdgeInsets.fromLTRB(0, 20, 0, 0),
                                      child: InkWell(
                                          onTap: () => Navigator.pop(context),
                                          child: Row(
                                              mainAxisAlignment:
                                                  MainAxisAlignment.center,
                                              children: <Widget>[
                                                Container(
                                                  margin:
                                                      EdgeInsets.only(right: 5),
                                                  child: Text(
                                                      snapshot
                                                          .data[index].quarter,
                                                      style: TextStyle(
                                                          fontSize: 20,
                                                          fontFamily:
                                                              'Montserrat',
                                                          color: Colors.blue),
                                                      textAlign:
                                                          TextAlign.left),
                                                )
                                              ])))));
                        });
                  }
              }
            }));
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: ChangeQuarter(),
    );
  }
}