首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Flutter FutureBuilder显示数据,然后在调用Rest API时消失(后端Laravel)

Flutter FutureBuilder显示数据,然后在调用Rest API时消失(后端Laravel)
EN

Stack Overflow用户
提问于 2020-11-21 19:49:37
回答 2查看 719关注 0票数 0

我正在运行一个带有laravel后端的flutter应用程序,我有一些问题。

问题是FutureBuilder显示数据,然后它就消失了;有时是length==4,然后它变成0,并且在Scaffold中显示“no data”

当我刷新代码时也是如此。

PS:我在本地主机上运行laravel,并使用真实的设备进行测试。

环境: Android Studio、Windows 10、Real device

Laravel项目:https://github.com/brakenseddik/blog_api_laravel

Flutter项目:https://github.com/brakenseddik/blog_api_flutter

导入'package:http/http.dart‘作为http;

代码语言:javascript
复制
class Repository {
  String _baseUrl = 'http://192.168.1.2:8000/api';
  httpGet(String api) async {
    return await http.get(_baseUrl + '/' + api);
  }
}

这里是主页的源代码

代码语言:javascript
复制
 import 'dart:convert';

import 'package:blog_api/models/post_model.dart';
import 'package:blog_api/services/post_service.dart';
import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  PostService _postService = PostService();
  List<PostModel> _list = List<PostModel>();

  Future<List<PostModel>> _getPosts() async {
    var result = await _postService.getAllPosts();
    _list = [];
    if (result != null) {
      var blogPosts = json.decode(result.body);
      blogPosts.forEach((post) {
        PostModel model = PostModel();
        setState(() {
          model.title = post['title'];
          model.details = post['details'];
          model.imageUrl = post['featured_image_url'];
          _list.add(model);
        });
      });
    }

    return _list;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Blog App'),
        ),
        body: FutureBuilder(
          future: _getPosts(),
          builder:
              (BuildContext context, AsyncSnapshot<List<PostModel>> snapshot) {
            print('length of list ${_list.length}');
            _list = snapshot.data;
            if (_list.length == 0) {
              return Center(
                child: Text('No data'),
              );
            } else if (!snapshot.hasData) {
              return Center(
                child: CircularProgressIndicator(),
              );
            } else {
              return ListView.builder(
                  itemCount: snapshot.data.length,
                  itemBuilder: (context, index) {
                    return Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Card(
                        child: Column(
                          children: [
                            Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Image.network(
                                snapshot.data[index].imageUrl,
                                height: 150,
                                //  width: double.maxFinite,
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Text(
                                snapshot.data[index].title,
                                style: TextStyle(
                                    fontSize: 18, fontWeight: FontWeight.w700),
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Text(
                                snapshot.data[index].details.substring(0, 25),
                                style: TextStyle(
                                  fontSize: 16,
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                    );
                  });
            }
          },
        ));
  }
}

和PostService

代码语言:javascript
复制
import 'package:blog_api/repository/repository.dart';

class PostService {
  Repository _repository;
  PostService() {
    _repository = Repository();
  }
  getAllPosts() async {
    return await _repository.httpGet('get-posts');
  }
}
EN

回答 2

Stack Overflow用户

发布于 2020-11-21 20:26:17

只需不使用setState即可运行代码

代码语言:javascript
复制
blogPosts.forEach((post) {
PostModel model = PostModel();
model.title = post['title'];
model.details = post['details'];
model.imageUrl = post['featured_image_url'];
_list.add(model);

FutureBuilder最初会使用还没有任何数据的快照来调用它的构建器。一旦它接收到数据,它将再次调用其构建器。因此,由于_list为空,if (_list.length == 0)将导致NPE。

代码语言:javascript
复制
if (!snapshot.hasData) {
  return Center(
    child: CircularProgressIndicator(),
  );
} else if (snapshot.data.length == 0) {
  return Center(
    child: Text('No data'),
  );
} else {
  return ListView.builder( 
  //...
}
票数 1
EN

Stack Overflow用户

发布于 2020-11-21 22:09:44

代码语言:javascript
复制
future: _getPosts(),

别干那事。这意味着每次调用build时,您都会再次查询您的API。

创建一个Future<List<PostModel>>类型的变量,将_getPosts()赋给它一次,然后将该变量与您的FutureBuilder一起使用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64942703

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档