peng8350/flutter_pulltorefresh
a widget provided to the flutter scroll component drop-down refresh and pull up load.
go to github downloadflutter_pulltorefresh
Intro
a widget provided to the flutter scroll component drop-down refresh and pull up load.support android and ios.
If you are Chinese,click here(中文文档)
Features
- pull up load and pull down refresh
- It’s almost fit for all Scroll witgets,like GridView,ListView…
- provide global setting of default indicator and property
- provide some most common indicators
- Support Android and iOS default ScrollPhysics,the overScroll distance can be controlled,custom spring animate,damping,speed.
- horizontal and vertical refresh,support reverse ScrollView also(four direction)
- provide more refreshStyle: Behind,Follow,UnFollow,Front,provide more loadmore style
- Support twoLevel refresh,implments just like TaoBao twoLevel,Wechat TwoLevel
- enable link indicator which placing other place,just like Wechat FriendCircle refresh effect
Usage
add this line to pubspec.yaml
dependencies:
pull_to_refresh: ^2.0.0
import package
import 'package:pull_to_refresh/pull_to_refresh.dart';
simple example,It must be noted here that ListView must be the child of SmartRefresher and cannot be separated from it. For detailed reasons, see here
List<String> items = ["1", "2", "3", "4", "5", "6", "7", "8"];
RefreshController _refreshController =
RefreshController(initialRefresh: false);
void _onRefresh() async{
// monitor network fetch
await Future.delayed(Duration(milliseconds: 1000));
// if failed,use refreshFailed()
_refreshController.refreshCompleted();
}
void _onLoading() async{
// monitor network fetch
await Future.delayed(Duration(milliseconds: 1000));
// if failed,use loadFailed(),if no data return,use LoadNodata()
items.add((items.length+1).toString());
if(mounted)
setState(() {
});
_refreshController.loadComplete();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SmartRefresher(
enablePullDown: true,
enablePullUp: true,
header: WaterDropHeader(),
footer: CustomFooter(
builder: (BuildContext context,LoadStatus mode){
Widget body ;
if(mode==LoadStatus.idle){
body = Text("pull up load");
}
else if(mode==LoadStatus.loading){
body = CupertinoActivityIndicator();
}
else if(mode == LoadStatus.failed){
body = Text("Load Failed!Click retry!");
}
else if(mode == LoadStatus.canLoading){
body = Text("release to load more");
}
else{
body = Text("No more Data");
}
return Container(
height: 55.0,
child: Center(child:body),
);
},
),
controller: _refreshController,
onRefresh: _onRefresh,
onLoading: _onLoading,
child: ListView.builder(
itemBuilder: (c, i) => Card(child: Center(child: Text(items[i]))),
itemExtent: 100.0,
itemCount: items.length,
),
),
);
}
// from 1.5.0, it is not necessary to add this line
//@override
// void dispose() {
// TODO: implement dispose
// _refreshController.dispose();
// super.dispose();
// }
The global configuration RefreshConfiguration, which configures all Smart Refresher representations under the subtree, is generally stored at the root of MaterialApp and is similar in usage to ScrollConfiguration.
In addition, if one of your SmartRefresher behaves differently from the rest of the world, you can use RefreshConfiguration.copyAncestor() to copy attributes from your ancestor RefreshConfiguration and replace
attributes that are not empty.
// Smart Refresher under the global configuration subtree, here are a few particularly important attributes
RefreshConfiguration(
headerBuilder: () => WaterDropHeader(), // Configure the default header indicator. If you have the same header indicator for each page, you need to set this
footerBuilder: () => ClassicFooter(), // Configure default bottom indicator
headerTriggerDistance: 80.0, // header trigger refresh trigger distance
springDescription:SpringDescription(stiffness: 170, damping: 16, mass: 1.9), // custom spring back animate,the props meaning see the flutter api
maxOverScrollExtent :100, //The maximum dragging range of the head. Set this property if a rush out of the view area occurs
maxUnderScrollExtent:0, // Maximum dragging range at the bottom
enableScrollWhenRefreshCompleted: true, //This property is incompatible with PageView and TabBarView. If you need TabBarView to slide left and right, you need to set it to true.
enableLoadingWhenFailed : true, //In the case of load failure, users can still trigger more loads by gesture pull-up.
hideFooterWhenNotFull: false, // Disable pull-up to load more functionality when Viewport is less than one screen
enableBallisticLoad: true, // trigger load more by BallisticScrollActivity
child: MaterialApp(
........
)
);
1.5.6 add new feather: localization ,you can add following code in MaterialApp or CupertinoApp:
MaterialApp(
localizationsDelegates: [
// this line is important
RefreshLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalMaterialLocalizations.delegate
],
supportedLocales: [
const Locale('en'),
const Locale('zh'),
],
localeResolutionCallback:
(Locale locale, Iterable<Locale> supportedLocales) {
//print("change language");
return locale;
},
)
ScreenShots
Examples
Style | basic | header in other place | reverse + horizontal |
---|---|---|---|
![]() |
![]() |
![]() |
Style | twoLevel | use with other widgets | chat |
---|---|---|---|
![]() |
![]() |
![]() |
Style | simple custom header(使用SpinKit) | dragableScrollSheet+LoadMore | Gif Indicator |
---|---|---|---|
![]() |
![]() |
![]() |
Indicator
各种指示器
refresh style | pull up load style | ||
---|---|---|---|
RefreshStyle.Follow ![]() |
RefreshStyle.UnFollow ![]() |
LoadStyle.ShowAlways ![]() |
LoadStyle.HideAlways![]() |
RefreshStyle.Behind ![]() |
RefreshStyle.Front ![]() |
LoadStyle.ShowWhenLoading![]() |
Style | ClassicIndicator | WaterDropHeader | MaterialClassicHeader |
---|---|---|---|
![]() |
![]() |
![]() |
Style | WaterDropMaterialHeader | Shimmer Indicator | Bezier+Circle |
---|---|---|---|
![]() |
![]() |
![]() |
about SmartRefresher’s child explain
Since 1.4.3, the child attribute has changed from ScrollView to Widget, but this does not mean that all widgets are processed the same. SmartRefresher’s internal implementation mechanism is not like NestedScrollView
There are two main types of processing mechanisms here, the first category
is the component inherited from ScrollView. At present, there are only three types,
ListView
, GridView
, CustomScrollView
. The second category
is components that are not inherited from ScrollView, which generally put empty views,
NoScrollable views (NoScrollable convert Scrollable), PageView, and you don’t need to estimate height by LayoutBuilder
yourself.
For the first type of mechanism, slivers are taken out of the system “illegally”. The second is to put children directly into classes such as `SliverToBox Adapter’. By splicing headers and footers back and forth to form slivers, and then putting slivers inside Smart Refresher into CustomScrollView, you can understand Smart Refresher as CustomScrollView,
because the inside is to return to CustomScrollView. So, there’s a big difference between a child node and a ScrollView.
Now, guess you have a requirement: you need to add background, scrollbars or something outside ScrollView. Here’s a demonstration of errors and correct practices
//error
SmartRefresher(
child: ScrollBar(
child: ListView(
....
)
)
)
// right
ScrollBar(
child: SmartRefresher(
child: ListView(
....
)
)
)
Demonstrate another wrong doing,put ScrollView in another widget
//error
SmartRefresher(
child:MainView()
)
class MainView extends StatelessWidget{
Widget build(){
return ListView(
....
);
}
}
The above mistake led to scrollable nesting another scrollable, causing you to not see the header and footer no matter how slippery you are.
Similarly, you may need to work with components like NotificationListener, ScrollConfiguration…, remember, don’t store them outside ScrollView (you want to add refresh parts) and Smart Refresher memory.。
More
Exist Problems
- about NestedScrollView,When you slide down and then slide up quickly, it will return back. The main reason is that
NestedScrollView does not consider the problem of cross-border elasticity under
bouncingScrollPhysics. Relevant flutter issues: 34316, 33367, 29264. This problem
can only wait for flutter to fix this. - SmartRefresher does not have refresh injection into ScrollView under the subtree, that is, if you put AnimatedList or RecordableListView in the child
is impossible. I have tried many ways to solve this problem and failed. Because of the
principle of implementation, I have to append it to the head and tail of slivers. In fact, the problem is not that much of my
Component issues, such as AnimatedList, can’t be used with AnimatedList and GridView unless
I convert AnimatedList to SliverAnimatedList is the solution. At the moment,
I have a temporary solution to this problem, but it’s a bit cumbersome to rewrite the code inside it and then outside ScrollView.
Add SmartRefresher, see my two examples Example 1和Example 2
Thanks
LICENSE
MIT License
Copyright (c) 2018 Jpeng
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.
![](/images/banner-woo.jpg)
excellent projects related to peng8350/flutter_pulltorefresh recommend downloading
AppFlowy
47859
AppFlowy is an open-source alternative to Notion. You are in charge of your data and customizations. Built with Flutter and Rust.
localsend
33797
An open-source cross-platform alternative to AirDrop
spotube
23772
🎧 Open source Spotify client that doesn't require Premium nor uses Electron! Available for both desktop & mobile!
revanced-manager
15035
💊 Application to use ReVanced on Android
gsy_github_app_flutter
14559
Flutter 超完整的开源项目,功能丰富,适合学习和日常使用。GSYGithubApp系列的优势:我们目前已经拥有Flutter、Weex、ReactNative、kotlin 四个版本。 功能齐全,项目框架内技术涉及面广,完成度高,持续维护,配套文章,适合全面学习,对比参考。跨平台的开源Github客户端App,更好的体验,更丰富的功能,旨在更好的日常管理和维护个人Github,提供更好更方便的驾车体验Σ( ̄。 ̄ノ)ノ。同款Weex版本 : https://github.com/CarGuo/GSYGithubAppWeex 、同款React Native版本 : https://github.com/CarGuo/GSYGithubApp 、原生 kotlin 版本 https://github.com/CarGuo/GSYGithubAppKotlin
dio
12249
A powerful HTTP client for Dart and Flutter, which supports global settings, Interceptors, FormData, aborting and canceling a request, files uploading and downloading, requests timeout, custom adapters, etc.
gopeed
11832
A modern download manager that supports all platforms. Built with Golang and Flutter.
bloc
11441
A predictable state management library that helps implement the BLoC design pattern
getx
9899
Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.
flame
8846
A Flutter based game engine.
flutter_deer
7595
🦌 Flutter 练习项目(包括集成测试、可访问性测试)。内含完整UI设计图,更贴近真实项目的练习。Flutter practice project (including integration testing and accessibility testing). Contains complete UI design drawings for a more realistic practice project.
fish-redux
7343
An assembled flutter application framework.
hiddify-next
7232
Multi-platform auto-proxy client, supporting Sing-box, X-ray, TUIC, Hysteria, Reality, Trojan, SSH etc. It’s an open-source, secure and ad-free.
ente
6686
Fully open source, End to End Encrypted alternative to Google Photos and Apple Photos
fl_chart
6451
FL Chart is a highly customizable Flutter chart library that supports Line Chart, Bar Chart, Pie Chart, Scatter Chart, and Radar Chart.
pixez-flutter
6360
一个支持免代理直连及查看动图的第三方Pixiv flutter客户端
Flutter-Responsive-Admin-Panel-or-Dashboard
6355
Responsive Admin Panel or Dashboard using Flutter
aidea
6021
AIdea 是一款支持 GPT 以及国产大语言模型通义千问、文心一言等,支持 Stable Diffusion 文生图、图生图、 SDXL1.0、超分辨率、图片上色的全能型 APP。
riverpod
5828
A reactive caching and data-binding framework. Riverpod makes working with asynchronous code a breeze.
pikapika
5463
美观易用且无广告的漫画和游戏客户端,同时支持MacOS,Windows,Android,iOS。