我正在运行一个带有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;
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,
),
),
),
],
),
),
);
});
}
},
));
}
}和PostService
import 'package:blog_api/repository/repository.dart';
class PostService {
Repository _repository;
PostService() {
_repository = Repository();
}
getAllPosts() async {
return await _repository.httpGet('get-posts');
}
}发布于 2020-11-21 20:26:17
只需不使用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最初会使用还没有任何数据的快照来调用它的构建器。一旦它接收到数据,它将再次调用其构建器。因此,由于_list为空,if (_list.length == 0)将导致NPE。
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.data.length == 0) {
return Center(
child: Text('No data'),
);
} else {
return ListView.builder(
//...
}发布于 2020-11-21 22:09:44
future: _getPosts(),别干那事。这意味着每次调用build时,您都会再次查询您的API。
创建一个Future<List<PostModel>>类型的变量,将_getPosts()赋给它一次,然后将该变量与您的FutureBuilder一起使用。
https://stackoverflow.com/questions/64942703
复制相似问题