【问题标题】:Flutter FutureBuilder shows data then disappears when calling Rest API (Backend Laravel)Flutter FutureBuilder 在调用 Rest API(Backend Laravel)时显示数据然后消失
【发布时间】:2021-03-04 15:36:33
【问题描述】:

我正在运行一个带有 laravel 后端的颤振应用程序,但我遇到了一些问题。

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

刷新代码时也是这样。

PS:我在 localhost 上运行 laravel 并使用真机进行测试。

环境:Android Studio、Windows 10、真机

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

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

将“包:http/http.dart”导入为 http;

class Repository {
  String _baseUrl = 'http://192.168.1.2:8000/api';
  httpGet(String api) async {
    return await http.get(_baseUrl + '/' + api);
  }
}

这里是主页源代码

 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,
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                    );
                  });
            }
          },
        ));
  }
}

还有邮政服务

import 'package:blog_api/repository/repository.dart';

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

【问题讨论】:

    标签: laravel api flutter dart


    【解决方案1】:
    future: _getPosts(),
    

    不要那样做。这意味着每次调用 build 时,您都会再次查询您的 API

    创建一个Future&lt;List&lt;PostModel&gt;&gt; 类型的变量,将_getPosts() 分配给它一次,然后将该变量与您的FutureBuilder 一起使用。

    【讨论】:

    • 但是这个也会做同样的事情,你能澄清更多吗!
    • 嗯,显然你也需要听从其他帖子的建议。
    【解决方案2】:

    我认为问题在于您在_getPosts() 中调用setState。这将重建所有内容,并且永远不会回复FutureBuilder。直接运行不带setState的代码:

    blogPosts.forEach((post) {
    PostModel model = PostModel();
    model.title = post['title'];
    model.details = post['details'];
    model.imageUrl = post['featured_image_url'];
    _list.add(model);
    

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

    我会尝试更改 if 语句的顺序:

    if (!snapshot.hasData) {
      return Center(
        child: CircularProgressIndicator(),
      );
    } else if (snapshot.data.length == 0) {
      return Center(
        child: Text('No data'),
      );
    } else {
      return ListView.builder( 
      //...
    }
    

    【讨论】:

    • 是的,我用 POSTMAN 测试了 API,它工作正常
    • ════════ 小部件库捕获的异常═══════════════════════════ ══════════════════════════ 构建FutureBuilder>(脏,状态:_FutureBuilderState >#52aac):getter 'length' 在 null 上调用。接收者:null 尝试调用:长度
    • 我看到它在 getPosts 中调用了 setState,但它不应该这样做。更新了答案
    猜你喜欢
    • 2021-02-10
    • 2022-01-02
    • 2021-01-02
    • 1970-01-01
    • 2021-07-25
    • 2021-01-29
    • 2019-09-22
    • 1970-01-01
    • 2011-06-02
    相关资源
    最近更新 更多