flutter create --template=package refresh_loadmore
用以上命令创建一个package包,refresh_loadmore是我的包名(先去https://pub.flutter-io.cn/上搜索一下你的包名,确保不会出现重名)。
编写包的实现
在lib/refresh_loadmore.dart中实现功能
library refresh_loadmore;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class RefreshLoadmore extends StatefulWidget {
/// callback function on pull down to refresh | 下拉刷新时的回调函数
final Future<void> Function() onRefresh;
/// callback function on pull up to load more data | 上拉以加载更多数据的回调函数
final Future<void> Function() onLoadmore;
/// Whether it is the last page, if it is true, you can not load more | 是否为最后一页,如果为true,则无法加载更多
final bool isLastPage;
/// child widget | 子组件
final Widget child;
/// Prompt text when there is no more data at the bottom | 底部没有更多数据时的提示文字
final String noMoreText;
/// [noMoreText] text style | [noMoreText]的文字样式
final TextStyle noMoreTextStyle;
const RefreshLoadmore({
Key key,
@required this.child,
@required this.isLastPage,
this.noMoreText,
this.noMoreTextStyle,
this.onRefresh,
this.onLoadmore,
}) : super(key: key);
@override
_RefreshLoadmoreState createState() => _RefreshLoadmoreState();
}
class _RefreshLoadmoreState extends State<RefreshLoadmore> {
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
GlobalKey<RefreshIndicatorState>();
ScrollController _scrollController;
bool _isLoading = false;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
_scrollController.addListener(() async {
if (_scrollController.position.pixels >=
_scrollController.position.maxScrollExtent) {
if (_isLoading) {
return;
}
setState(() {
_isLoading = true;
});
if (widget.onLoadmore != null) {
await widget.onLoadmore();
}
setState(() {
_isLoading = false;
});
}
});
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
Widget mainWiget = ListView(
/// Solve the problem that there are too few items to pull down and refresh | 解决item太少,无法下拉刷新的问题
physics: AlwaysScrollableScrollPhysics(),
controller: _scrollController,
children: <Widget>[
widget.child,
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.all(16),
child: _isLoading
? CupertinoActivityIndicator()
: Text(
widget.isLastPage
? widget.noMoreText ?? 'No more data'
: '',
style: widget.noMoreTextStyle ??
TextStyle(
fontSize: 18,
color: Theme.of(context).disabledColor,
),
),
)
],
)
],
);
if (widget.onRefresh == null) {
return Scrollbar(child: mainWiget);
}
return RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: () async {
if (_isLoading) return;
await widget.onRefresh();
},
child: mainWiget,
);
}
}
创建一个example项目示例
在refresh_loadmore的根目录新建一个example项目
flutter create example
在example项目的pubspec.yaml中添加依赖
dependencies:
refresh_loadmore:
path: ../
在main.dart中编写示例代码
import 'package:flutter/material.dart';
import 'package:refresh_loadmore/refresh_loadmore.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.purple,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool isLastPage = false;
/// is the last page | 是否为最后一页
List list;
int page = 1;
@override
void initState() {
super.initState();
loadFirstData();
}
Future<void> loadFirstData() async {
await Future.delayed(Duration(seconds: 1), () {
setState(() {
list = [
'dddd',
'sdfasfa',
'sdfgaf',
'adsgafg',
'dddd',
'sdfasfa',
'sdfgaf',
'adsgafg',
'dddd',
'sdfasfa',
'sdfgaf',
'adsgafg'
'adsgafg',
'dddd',
'sdfasfa',
'sdfgaf',
'adsgafg'
];
isLastPage = false;
page = 1;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: list != null
? RefreshLoadmore(
onRefresh: loadFirstData,
onLoadmore: () async {
if (isLastPage) return;
await Future.delayed(Duration(seconds: 1), () {
setState(() {
list.addAll(['123', '234', '457']);
page++;
});
print(page);
if (page >= 3) {
setState(() {
isLastPage = true;
});
}
});
},
noMoreText: 'No more data, you are at the end',
isLastPage: isLastPage,
child: list.isNotEmpty
? Column(
children: list
.map(
(e) => ListTile(
title: Text(e),
trailing: Icon(Icons.accessibility_new),
),
)
.toList(),
)
: Center(
child: Text('empty'),
),
)
: Center(child: CircularProgressIndicator()),
);
}
}
测试效果图如下:
添加License和修改pubspec.yaml文件
修改包的LICENSE文件
MIT License
Copyright (c) 2020 shareven
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
修改pubspec.yaml
name: refresh_loadmore
description: A Flutter component that supports pull-down refresh and pull-up to load more data (一个组件,支持下拉刷新,上拉加载更多数据).
version: 1.0.1
homepage: https://github.com/shareven/refresh_loadmore
...
修改CHANGELOG.md
## [1.0.1]
* initRelease
发布
发布前用命令检查
flutter pub pub publish --dry-run
发布
flutter pub publish
注意
如果是没有访问外国网站的,在.bash_profile
或.zprofile里面设置了PUB_HOSTED_URL
和FLUTTER_STORAGE_BASE_URL
的记得注释掉这两个环境变量。
#export PUB_HOSTED_URL= https:// pub.flutter-io.cn
#export FLUTTER_STORAGE_BASE_URL= https:// storage.flutter-io.cn
flutter pub publish的时候要访问外国网站。请确保终端访问外国网站了。 (ping www.google.com)如果是通的,则可以执行。如果终端没有访问外国网站可以搜索一下proxifier
但是我这还是失败了
更换另一个地址,又成功了
flutter packages pub publish --server=https://pub.dartlang.org
提升分数
上传之后发现分数好低
提示我pubspec.yaml的description包含太多中文了,那就把中文去掉吧
name: refresh_loadmore
description: A Flutter component that supports pull-down refresh and pull-up to load more data
version: 1.0.2
homepage: https://github.com/shareven/refresh_loadmore
...
修改CHANGELOG.md
## [1.0.1]
* initRelease
## [1.0.2]
* remove Chinese description
重新发布
flutter pub pub publish --dry-run # 检查一下,没问题就发布
flutter packages pub publish --server=https://pub.dartlang.org
接下来就得靠各位读了本篇文章的观众大佬,点赞和下载使用,来提升分数了。感谢!感谢!