我创建了一个示例以使用 Web 服务加载更多数据
你可以看到这个例子,你可以为你实现json数据。
https://android-pratap.blogspot.com/2018/12/flutter-infinite-listview-using.html
import 'package:akeepo/randomuser_infinitelist.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: InfiniteUsersList(),
);
}
}
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class InfiniteUsersList extends StatefulWidget {
static String tag = 'users-page';
@override
State<StatefulWidget> createState() {
return new _InfiniteUsersListState();
}
}
class _InfiniteUsersListState extends State<InfiniteUsersList> {
List<User> users = new List<User>();
ScrollController _scrollController = new ScrollController();
bool isPerformingRequest = false;
int pageNumber = 0;
@override
void initState() {
super.initState();
// Loading initial data or first request to get the data
_getMoreData();
// Loading data after scroll reaches end of the list
_scrollController.addListener(() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
_getMoreData();
}
});
}
// to show progressbar while loading data in background
Widget _buildProgressIndicator() {
return new Padding(
padding: const EdgeInsets.all(8.0),
child: new Center(
child: new Opacity(
opacity: isPerformingRequest ? 1.0 : 0.0,
child: new CircularProgressIndicator(),
),
),
);
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
// Webservice request to load 20 users data using paging
Future<List<User>> _getUsers() async {
List<User> users = new List<User>();
setState(() {
pageNumber++;
});
String url =
"https://api.randomuser.me/?page=$pageNumber&results=20&seed=abc";
print(url);
var response = await http.get(url);
var jsonData = json.decode(response.body);
print(jsonData);
var usersData = jsonData["results"];
for (var user in usersData) {
User newUser = User(user["name"]["first"] + user["name"]["last"],
user["email"], user["picture"]["large"], user["phone"]);
users.add(newUser);
}
return users;
}
_getMoreData() async {
if (!isPerformingRequest) {
setState(() {
isPerformingRequest = true;
});
List<User> newEntries = await _getUsers(); //returns empty list
if (newEntries.isEmpty) {
double edge = 50.0;
double offsetFromBottom = _scrollController.position.maxScrollExtent -
_scrollController.position.pixels;
if (offsetFromBottom < edge) {
_scrollController.animateTo(
_scrollController.offset - (edge - offsetFromBottom),
duration: new Duration(milliseconds: 500),
curve: Curves.easeOut);
}
}
setState(() {
users.addAll(newEntries);
isPerformingRequest = false;
});
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Users',
style:
TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
body: Container(
child: ListView.builder(
shrinkWrap: true,
controller: _scrollController,
itemCount: users.length + 1,
itemBuilder: (BuildContext context, int index) {
if (index == users.length) {
return _buildProgressIndicator();
} else {
return ListTile(
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) =>
UserDetailPage(users[index])));
},
title: Text(users[index].fullName),
subtitle: Text(users[index].mobileNumber),
leading: CircleAvatar(
backgroundImage: NetworkImage(users[index].imageUrl)),
);
}
})),
);
}
}
class User {
final String fullName;
final String email;
final String imageUrl;
final String mobileNumber;
User(this.fullName, this.email, this.imageUrl, this.mobileNumber);
}
// User Detail Page
class UserDetailPage extends StatelessWidget {
final User user;
UserDetailPage(this.user);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("User Details"),
),
body: Center(
child: Text(
user.fullName,
style: TextStyle(fontSize: 35.0),
),
),
);
}
}