颤振拉起以从api提取数据

时间:2020-06-26 23:32:47

标签: flutter dart

我想使用刷新指示器,以便当您上拉页面时就可以进行重建了,我将与您分享我的代码,我已经尝试了很多次,但实际上我找不到正确的方法,这是我的代码

  class Companies {
  final int id;
  final String name;
  final String companyLogo;

  Companies({this.id, this.name, this.companyLogo});

  factory Companies.fromJson(Map<String, dynamic> json) {
    return Companies(
      id: json['id'],
      name: json['name'],
      companyLogo: json['company_logo'],
    );
  }
}

Future<List<Companies>> fetchCompanies() async {
  final response = await http.get('$webSiteUrl/company/api/fetch');
  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    return parseCompanies(response.body);
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load the companies');
  }
}


List<Companies> parseCompanies(String responseBody) {
  final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
  return parsed.map<Companies>((json) => Companies.fromJson(json)).toList();
}
    class CompaniesPage extends StatefulWidget{
      @override
      _CompaniesState createState() => _CompaniesState();
    }
    
    class _CompaniesState extends State<CompaniesPage> {
      var refreshKey = GlobalKey<RefreshIndicatorState>();
    
      Future<List<Companies>> companies;
      @override
    
      void initState() {
        super.initState();
        companies = fetchCompanies();
      }
    
      Future<Null> refreshCompanies() async {
        refreshKey.currentState?.show(atTop: false);
        setState(() {
          companies = fetchCompanies();
        });
    
        return await companies;
      }
    
      Widget build(BuildContext context) {
        checkVersion(context);
        return Scaffold(
          body: Center(
                child: FutureBuilder<List<Companies>>(
                  future: companies,
                  builder: (context, snapshot) {
                    if (snapshot.hasData) {
                      List<Companies> companies = snapshot.data;
                      if(companies.length >= 1){
                        return MainLayout(
                          RefreshIndicator(
                            key: refreshKey,
                            onRefresh: refreshCompanies,
                            child: GridView.count(
                              crossAxisCount: 2 ,
                              children: List.generate(companies.length, (index) {
                                return GestureDetector(
                                  onTap: () => {
                                    Navigator.push(
                                      context,
                                      MaterialPageRoute(builder: (context) => Categories(companies[index].id, companies[index].name)),
                                    )},
                                  child: CompaniesInterface(companies[index].id , companies[index].name , companies[index].companyLogo),
                                );
                              }),
                            ),
                          ),
                        );
                      }else{
                        return EmptyDataBase();
                      }
                    } else if (snapshot.hasError) {
                      return ConnectionError();
                    }
    
                    // By default, show a loading spinner.
                    return DefaultTabController(
                      length: 1,
                      child: TabBar(
                        indicatorColor: Colors.transparent,
                        tabs: <Widget>[
                          Tab(
                            child: LoadingBouncingGrid.square(
                              backgroundColor: Colors.cyan,
                              size: 40,
                            ),
                          ),
                        ],
                      ),
                    );
                  },
                ),
              ),
        );
      }
    }

如您所见,我已经对其进行了测试,但是它无法正确刷新页面。我想要的是如何在上拉时重建此页面,因此我认为代码中缺少的部分是refreshCompanies()函数< / p>

更新:

class _CompaniesState extends State<CompaniesPage> {
  StreamController<List<Companies>> companiesStreamController;
  var refreshKey = GlobalKey<RefreshIndicatorState>();

  Future<List<Companies>> fetchCompanies() async {
    final response = await http.get('$webSiteUrl/company/api/fetch');
    if (response.statusCode == 200) {
      // If the server did return a 200 OK response,
      // then parse the JSON.
      return parseCompanies(response.body);
    } else {
      // If the server did not return a 200 OK response,
      // then throw an exception.
      throw Exception('Failed to load the companies');
    }
  }

  loadCompanies() async {
    fetchCompanies().then((result) async {
      companiesStreamController.add(result);
      return result;
    });
  }

  Future<Null> refreshCompanies() async {
    refreshKey.currentState.show(atTop: true);
    setState(() {
      loadCompanies();
    });
  }
  
  @override
  void initState() {
    checkVersion(context);
    companiesStreamController = new StreamController();
    Timer.periodic(Duration(seconds: 1), (_) => loadCompanies());
    super.initState();
  }

  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: StreamBuilder<List<Companies>>(
          stream: companiesStreamController.stream,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              List<Companies> companies = snapshot.data;
              if(companies.length >= 1){
                return MainLayout(
                  RefreshIndicator(
                    onRefresh: refreshCompanies,
                    key: refreshKey,
                    child: GridView.count(
                      crossAxisCount: 2 ,
                      children: List.generate(companies.length, (index) {
                        return GestureDetector(
                          onTap: () => {
                            Navigator.push(
                              context,
                              MaterialPageRoute(builder: (context) => Categories(companies[index].id, companies[index].name)),
                            )},
                          child: CompaniesInterface(companies[index].id , companies[index].name , companies[index].companyLogo),
                        );
                      }),
                    ),
                  ),
                );
              }else{......rest of code

1 个答案:

答案 0 :(得分:0)

添加一个StreamController

StreamController<List<Companies>> dataController;

在您的initState中将其初始化:

dataController = StreamController();

将fetchCompanies移动到您的小部件中,然后在返回结果之前将其添加到您的流中:

var result = parseCompanies(response.body);
dataController.add(result);

使用StreamBuilder代替FutureBuilder

StreamBuilder<List<Companies>>(
  stream: dataController.stream,
  builder: (context, snapshot) {
     ...
  }
)