1、搭建flutter的开发环境:http://www.haijin.xyz/article/730
2、创建一个项目:
flutter create myapp
项目结构:
4、相关代码:
wallpaper_detail_api.dart:
import '../network/api_service.dart';
class WallpaperDetailApi {
final ApiService _apiService = ApiService();
void fetchTodoData({
int? currentPage,
int? pageSize,
int? typeId,
String? name,
required Function(dynamic data) callBack,
}) {
var body = {
"currentPage":currentPage,
"pageSize":pageSize,
"typeId":typeId,
"name":name,
};
_apiService.get(
url: 'http://192.168.97.13:5800/api',
body: body,
callbackFunc:callBack,
);
}
}
wallpaper_detail.dart:
/// total : 55052
/// pageNo : 1
/// pageSize : 5506
class WallpaperDetail {
WallpaperDetail({
num? total,
num? pageNo,
num? pageSize,
List<Records>? records,
}) {
_total = total;
_pageNo = pageNo;
_pageSize = pageSize;
_records = records;
}
WallpaperDetail.fromJson(dynamic json) {
_total = json['total'];
_pageNo = json['pageNo'];
_pageSize = json['pageSize'];
if (json['records'] != null) {
_records = [];
json['records'].forEach((v) {
_records?.add(Records.fromJson(v));
});
}
}
num? _total;
num? _pageNo;
num? _pageSize;
List<Records>? _records;
WallpaperDetail copyWith({
num? total,
num? pageNo,
num? pageSize,
List<Records>? records,
}) =>
WallpaperDetail(
total: total ?? _total,
pageNo: pageNo ?? _pageNo,
pageSize: pageSize ?? _pageSize,
records: records ?? _records,
);
num? get total => _total;
num? get pageNo => _pageNo;
num? get pageSize => _pageSize;
List<Records>? get records => _records;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['total'] = _total;
map['pageNo'] = _pageNo;
map['pageSize'] = _pageSize;
final records = _records;
if (records != null) {
map['records'] = records.map((v) => v.toJson()).toList();
}
return map;
}
}
/// id : 1933
/// wallpaperName : "甜美Lolita少女壁纸"
/// wallpaperListUrl : "https://up.enterdesk.com/edpic_360_360/cb/57/b9/cb57b98151247cd5a6e5211f05e460e3.jpg"
/// wallpaperType : 1
/// remark : ""
/// wallpaperDetailUrl : "https://up.enterdesk.com/edpic_source/cb/57/b9/cb57b98151247cd5a6e5211f05e460e3.jpg"
class Records {
Records({
num? id,
String? wallpaperName,
String? wallpaperListUrl,
num? wallpaperType,
String? remark,
String? wallpaperDetailUrl,
}) {
_id = id;
_wallpaperName = wallpaperName;
_wallpaperListUrl = wallpaperListUrl;
_wallpaperType = wallpaperType;
_remark = remark;
_wallpaperDetailUrl = wallpaperDetailUrl;
}
Records.fromJson(dynamic json) {
_id = json['id'];
_wallpaperName = json['wallpaperName'];
_wallpaperListUrl = json['wallpaperListUrl'];
_wallpaperType = json['wallpaperType'];
_remark = json['remark'];
_wallpaperDetailUrl = json['wallpaperDetailUrl'];
}
num? _id;
String? _wallpaperName;
String? _wallpaperListUrl;
num? _wallpaperType;
String? _remark;
String? _wallpaperDetailUrl;
Records copyWith({
num? id,
String? wallpaperName,
String? wallpaperListUrl,
num? wallpaperType,
String? remark,
String? wallpaperDetailUrl,
}) =>
Records(
id: id ?? _id,
wallpaperName: wallpaperName ?? _wallpaperName,
wallpaperListUrl: wallpaperListUrl ?? _wallpaperListUrl,
wallpaperType: wallpaperType ?? _wallpaperType,
remark: remark ?? _remark,
wallpaperDetailUrl: wallpaperDetailUrl ?? _wallpaperDetailUrl,
);
num? get id => _id;
String? get wallpaperName => _wallpaperName;
String? get wallpaperListUrl => _wallpaperListUrl;
num? get wallpaperType => _wallpaperType;
String? get remark => _remark;
String? get wallpaperDetailUrl => _wallpaperDetailUrl;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = _id;
map['wallpaperName'] = _wallpaperName;
map['wallpaperListUrl'] = _wallpaperListUrl;
map['wallpaperType'] = _wallpaperType;
map['remark'] = _remark;
map['wallpaperDetailUrl'] = _wallpaperDetailUrl;
return map;
}
}
home_page.dart:(这部分是重点)
import 'package:flutter/material.dart';
import 'package:myapp/api/wallpaper_detail_api.dart';
import 'package:myapp/model/wallpaper_detail.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin {
final WallpaperDetailApi _wallpaperDetailApi = WallpaperDetailApi();
WallpaperDetail? _wallpaper;
List<Records> _records = [];
// 页码
int _currentPage = 1;
// 是否正在刷新
bool _isRefreshing = false;
// 是否正在加载更多
bool _isLoadingMore = false;
double _listHeight = 0.0; // 列表的高度
final ScrollController _scrollController = ScrollController();
// 索引
int _itemIndex = 0;
@override
void initState() {
// TODO: implement initState
super.initState();
_scrollController.addListener((){
// 滑动到底部,去做加载更多的请求
print("_itemIndex:$_itemIndex");
print(_records.length);
if(_itemIndex + 5 > _records.length){
if (!_isLoadingMore) {
print("加载更多");
_currentPage++;
_fetchData();
}
}
});
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
Future<void> _fetchData() async {
try{
print("页码数:");
print(_currentPage);
_wallpaperDetailApi.fetchTodoData(currentPage: _currentPage,callBack: _analyzeWallpaperData);
} catch(e) {
print(e);
}
}
// 拉下刷新函数
Future<void> _refreshFunc() async {
print("刷新");
_currentPage = 1;
_fetchData();
}
// 解析获取的数据
void _analyzeWallpaperData(dynamic data) {
_wallpaper = WallpaperDetail.fromJson(data);
print("获取的数据");
if (_currentPage == 1) {
// 如果是第一页,则替换列表
setState(() {
_records = _wallpaper!.records!;
});
} else {
// 如果不是第一页,则追加到列表末尾
setState(() {
_wallpaper!.records?.forEach((item){
_records.add(item);
});
});
}
setState(() {
_isRefreshing = false;
_isLoadingMore = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('壁纸列表'),
),
body: RefreshIndicator(
onRefresh: _refreshFunc, // 下拉刷新
child: _wallpaper == null
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
setState(() {
_currentPage = 1; // 重置页码
// _records.clear(); // 清空列表
});
_fetchData(); // 获取第一页数据
},
child: Text('获取壁纸'),
),
],
),
) : ListView.builder(
itemCount: (_wallpaper?.pageSize??0) as int,
itemBuilder: (context, index) {
_itemIndex = index;
if(index > _currentPage * 10 - 5){
if (!_isLoadingMore) {
print("加载更多");
_currentPage++;
_fetchData();
}
}
if (index < _records!.length) {
final item = _records?[index];
return ListTile(
leading: Image.network(item!.wallpaperListUrl??""),
title: Text(item!.wallpaperName??""),
subtitle: Text('ID: ${item?.id}'),
onTap: () {
print("跳转到壁纸的详情页面");
},
);
} else {
return Container(
height: 50,
alignment: Alignment.center,
child: CircularProgressIndicator(),
);
}
},
// controller: _scrollController,
),
),
);
}
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
}
滑动的核心在: itemBuilder: (context, index) 这段代码里
if(index > _currentPage * 10 - 5){
if (!_isLoadingMore) {
print("加载更多");
_currentPage++;
_fetchData();
}
}
上面的那个_scrollController也可以使用,但没必要了。
运行截图: