[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-9206":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":20,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":24,"readmeContent":25,"aiSummary":26,"trendingCount":16,"starSnapshotCount":16,"syncStatus":27,"lastSyncTime":28,"discoverSource":29},9206,"flutter_pulltorefresh","peng8350\u002Fflutter_pulltorefresh","peng8350","a widget provided to the flutter scroll component drop-down refresh and pull up load.","",null,"Dart",2737,759,26,145,0,1,30.64,"MIT License",false,"master",true,[],"2026-06-12 02:02:04","# flutter_pulltorefresh\n\u003Ca href=\"https:\u002F\u002Fpub.dev\u002Fpackages\u002Fpull_to_refresh\">\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fpub\u002Fv\u002Fpull_to_refresh.svg\"\u002F>\n\u003C\u002Fa>\n\u003Ca href=\"https:\u002F\u002Fflutter.dev\u002F\">\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fflutter-%3E%3D%202.0.0-green.svg\"\u002F>\n\u003C\u002Fa>\n\u003Ca href=\"https:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT\">\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-yellow.svg\"\u002F>\n\u003C\u002Fa>\n\n## Intro\na widget provided to the flutter scroll component drop-down refresh and pull up load.support android and ios.\nIf you are Chinese,click here([中文文档](https:\u002F\u002Fgithub.com\u002Fpeng8350\u002Fflutter_pulltorefresh\u002Fblob\u002Fmaster\u002FREADME_CN.md))\n\n\n\n## Features\n* pull up load and pull down refresh\n* It's almost fit for all Scroll witgets,like GridView,ListView...\n* provide global setting of default indicator and property\n* provide some most common indicators\n* Support Android and iOS default ScrollPhysics,the overScroll distance can be controlled,custom spring animate,damping,speed.\n* horizontal and vertical refresh,support reverse ScrollView also(four direction)\n* provide more refreshStyle: Behind,Follow,UnFollow,Front,provide more loadmore style\n* Support twoLevel refresh,implments just like TaoBao twoLevel,Wechat TwoLevel\n* enable link indicator which placing other place,just like Wechat FriendCircle refresh effect\n\n## Usage\n\nadd this line to pubspec.yaml\n\n```yaml\n\n   dependencies:\n\n    pull_to_refresh: ^2.0.0\n\n\n```\n\nimport package\n\n```dart\n\n    import 'package:pull_to_refresh\u002Fpull_to_refresh.dart';\n\n```\n\nsimple example,***It must be noted here that ListView must be the child of SmartRefresher and cannot be separated from it. For detailed reasons, see \u003Ca href=\"child\">here\u003C\u002Fa>***\n\n```dart\n\n\n  List\u003CString> items = [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"];\n  RefreshController _refreshController =\n      RefreshController(initialRefresh: false);\n\n  void _onRefresh() async{\n    \u002F\u002F monitor network fetch\n    await Future.delayed(Duration(milliseconds: 1000));\n    \u002F\u002F if failed,use refreshFailed()\n    _refreshController.refreshCompleted();\n  }\n\n  void _onLoading() async{\n    \u002F\u002F monitor network fetch\n    await Future.delayed(Duration(milliseconds: 1000));\n    \u002F\u002F if failed,use loadFailed(),if no data return,use LoadNodata()\n    items.add((items.length+1).toString());\n    if(mounted)\n    setState(() {\n\n    });\n    _refreshController.loadComplete();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      body: SmartRefresher(\n        enablePullDown: true,\n        enablePullUp: true,\n        header: WaterDropHeader(),\n        footer: CustomFooter(\n          builder: (BuildContext context,LoadStatus mode){\n            Widget body ;\n            if(mode==LoadStatus.idle){\n              body =  Text(\"pull up load\");\n            }\n            else if(mode==LoadStatus.loading){\n              body =  CupertinoActivityIndicator();\n            }\n            else if(mode == LoadStatus.failed){\n              body = Text(\"Load Failed!Click retry!\");\n            }\n            else if(mode == LoadStatus.canLoading){\n                body = Text(\"release to load more\");\n            }\n            else{\n              body = Text(\"No more Data\");\n            }\n            return Container(\n              height: 55.0,\n              child: Center(child:body),\n            );\n          },\n        ),\n        controller: _refreshController,\n        onRefresh: _onRefresh,\n        onLoading: _onLoading,\n        child: ListView.builder(\n          itemBuilder: (c, i) => Card(child: Center(child: Text(items[i]))),\n          itemExtent: 100.0,\n          itemCount: items.length,\n        ),\n      ),\n    );\n  }\n\n  \u002F\u002F from 1.5.0, it is not necessary to add this line\n  \u002F\u002F@override\n \u002F\u002F void dispose() {\n    \u002F\u002F TODO: implement dispose\n  \u002F\u002F  _refreshController.dispose();\n  \u002F\u002F  super.dispose();\n \u002F\u002F }\n\n```\n\nThe 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.\nIn 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\nattributes that are not empty.\n\n```dart\n    \u002F\u002F Smart Refresher under the global configuration subtree, here are a few particularly important attributes\n     RefreshConfiguration(\n         headerBuilder: () => WaterDropHeader(),        \u002F\u002F Configure the default header indicator. If you have the same header indicator for each page, you need to set this\n         footerBuilder:  () => ClassicFooter(),        \u002F\u002F Configure default bottom indicator\n         headerTriggerDistance: 80.0,        \u002F\u002F header trigger refresh trigger distance\n         springDescription:SpringDescription(stiffness: 170, damping: 16, mass: 1.9),         \u002F\u002F custom spring back animate,the props meaning see the flutter api\n         maxOverScrollExtent :100, \u002F\u002FThe maximum dragging range of the head. Set this property if a rush out of the view area occurs\n         maxUnderScrollExtent:0, \u002F\u002F Maximum dragging range at the bottom\n         enableScrollWhenRefreshCompleted: true, \u002F\u002FThis property is incompatible with PageView and TabBarView. If you need TabBarView to slide left and right, you need to set it to true.\n         enableLoadingWhenFailed : true, \u002F\u002FIn the case of load failure, users can still trigger more loads by gesture pull-up.\n         hideFooterWhenNotFull: false, \u002F\u002F Disable pull-up to load more functionality when Viewport is less than one screen\n         enableBallisticLoad: true, \u002F\u002F trigger load more by BallisticScrollActivity\n        child: MaterialApp(\n            ........\n        )\n    );\n\n```\n\n1.5.6 add new feather: localization ,you can add following code in MaterialApp or CupertinoApp:\n\n```dart\n\n    MaterialApp(\n            localizationsDelegates: [\n              \u002F\u002F this line is important\n              RefreshLocalizations.delegate,\n              GlobalWidgetsLocalizations.delegate,\n              GlobalMaterialLocalizations.delegate\n            ],\n            supportedLocales: [\n              const Locale('en'),\n              const Locale('zh'),\n            ],\n            localeResolutionCallback:\n                (Locale locale, Iterable\u003CLocale> supportedLocales) {\n              \u002F\u002Fprint(\"change language\");\n              return locale;\n            },\n    )\n\n```\n\n\n## ScreenShots\n\n\n\n### Examples\n|Style| [basic](example\u002Flib\u002Fui\u002Fexample\u002FuseStage\u002Fbasic.dart) | [header in other place](example\u002Flib\u002Fui\u002Fexample\u002Fcustomindicator\u002Flink_header_example.dart) | [reverse + horizontal](example\u002Flib\u002Fui\u002Fexample\u002FuseStage\u002Fhorizontal+reverse.dart) |\n|:---:|:---:|:---:|:---:|\n|| ![](arts\u002Fexample1.gif) | ![](arts\u002Fexample2.gif) |![](arts\u002Fexample3.gif) |\n\n|Style|  [twoLevel](example\u002Flib\u002Fui\u002Fexample\u002FuseStage\u002Ftwolevel_refresh.dart) |[use with other widgets](example\u002Flib\u002Fui\u002Fexample\u002Fotherwidget) |  [chat](example\u002Flib\u002Fui\u002Fexample\u002FuseStage\u002Fqq_chat_list.dart) |\n|:---:|:---:|:---:|:---:|\n||  ![](arts\u002Fexample4.gif) |![](arts\u002Fexample5.gif) | ![](arts\u002Fexample6.gif) |\n\n\n|Style| [simple custom header(使用SpinKit)](example\u002Flib\u002Fui\u002Fexample\u002Fcustomindicator\u002Fspinkit_header.dart)| [dragableScrollSheet+LoadMore](example\u002Flib\u002Fui\u002Fexample\u002Fotherwidget\u002Fdraggable_bottomsheet_loadmore.dart)|[Gif Indicator](example\u002Flib\u002Fui\u002Fexample\u002Fcustomindicator\u002Fgif_indicator_example1.dart) |\n|:---:|:---:|:---:|:---:|\n|| ![](arts\u002Fexample7.gif) | ![](arts\u002Fexample8.gif) | ![](arts\u002Fgifindicator.gif) |\n\n\n\n### Indicator\n\n### 各种指示器\n\n| refresh style |   |pull up load style| |\n|:---:|:---:|:---:|:---:|\n| RefreshStyle.Follow \u003Cbr>![Follow](example\u002Fimages\u002Frefreshstyle1.gif)|RefreshStyle.UnFollow \u003Cbr> ![不跟随](example\u002Fimages\u002Frefreshstyle2.gif)| LoadStyle.ShowAlways \u003Cbr>  ![永远显示](example\u002Fimages\u002Floadstyle1.gif) | LoadStyle.HideAlways\u003Cbr> ![永远隐藏](example\u002Fimages\u002Floadstyle2.gif)|\n| RefreshStyle.Behind \u003Cbr> ![背部](example\u002Fimages\u002Frefreshstyle3.gif)| RefreshStyle.Front \u003Cbr> ![前面悬浮](example\u002Fimages\u002Frefreshstyle4.gif)| LoadStyle.ShowWhenLoading\u003Cbr>  ![当加载中才显示,其它隐藏](example\u002Fimages\u002Floadstyle3.gif) | |\n\n|Style| [ClassicIndicator](https:\u002F\u002Fgithub.com\u002Fpeng8350\u002Fflutter_pulltorefresh\u002Fblob\u002Fmaster\u002Flib\u002Fsrc\u002Findicator\u002Fclassic_indicator.dart) | [WaterDropHeader](https:\u002F\u002Fgithub.com\u002Fpeng8350\u002Fflutter_pulltorefresh\u002Fblob\u002Fmaster\u002Flib\u002Fsrc\u002Findicator\u002Fwaterdrop_header.dart) | [MaterialClassicHeader](https:\u002F\u002Fgithub.com\u002Fpeng8350\u002Fflutter_pulltorefresh\u002Fblob\u002Fmaster\u002Flib\u002Fsrc\u002Findicator\u002Fmaterial_indicator.dart) |\n|:---:|:---:|:---:|:---:|\n|| ![](example\u002Fimages\u002Fclassical_follow.gif) | ![](example\u002Fimages\u002Fwarterdrop.gif) | ![](example\u002Fimages\u002Fmaterial_classic.gif) |\n\n|Style|  [WaterDropMaterialHeader](https:\u002F\u002Fgithub.com\u002Fpeng8350\u002Fflutter_pulltorefresh\u002Fblob\u002Fmaster\u002Flib\u002Fsrc\u002Findicator\u002Fmaterial_indicator.dart) | [Shimmer Indicator](example\u002Flib\u002Fui\u002Fexample\u002Fcustomindicator\u002Fshimmer_indicator.dart) |[Bezier+Circle](https:\u002F\u002Fgithub.com\u002Fpeng8350\u002Fflutter_pulltorefresh\u002Fblob\u002Fmaster\u002Flib\u002Fsrc\u002Findicator\u002Fbezier_indicator.dart) |\n|:---:|:---:|:---:|:---:|\n||  ![](example\u002Fimages\u002Fmaterial_waterdrop.gif) |![](example\u002Fimages\u002Fshimmerindicator.gif) | ![](example\u002Fimages\u002Fbezier.gif) |\n\n\n\u003Ca name=\"child\">\u003C\u002Fa>\n\n## about SmartRefresher's child explain\n\nSince 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\u003Cbr>\u003Cbr>\nThere are two main types of processing mechanisms here, `the first category`is the component inherited from ScrollView. At present, there are only three types,\n `ListView`, `GridView`, `CustomScrollView`. ` The second category ` is components that are not inherited from ScrollView, which generally put empty views,\n  NoScrollable views (NoScrollable convert Scrollable), PageView, and you don't need to estimate height  by `LayoutBuilder` yourself.\n\u003Cbr>\u003Cbr>\nFor 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,\nbecause the inside is to return to CustomScrollView. So, there's a big difference between a child node and a ScrollView.\n\u003Cbr>\u003Cbr>\nNow, guess you have a requirement: you need to add background, scrollbars or something outside ScrollView. Here's a demonstration of errors and correct practices\n\n```dart\n\n   \u002F\u002Ferror\n   SmartRefresher(\n      child: ScrollBar(\n          child: ListView(\n             ....\n      )\n    )\n   )\n\n   \u002F\u002F right\n   ScrollBar(\n      child: SmartRefresher(\n          child: ListView(\n             ....\n      )\n    )\n   )\n\n```\n\nDemonstrate another wrong doing,put ScrollView in another widget\n\n```dart\n\n   \u002F\u002Ferror\n   SmartRefresher(\n      child:MainView()\n   )\n\n   class MainView extends StatelessWidget{\n       Widget build(){\n          return ListView(\n             ....\n          );\n       }\n\n   }\n\n```\n\nThe above mistake led to scrollable nesting another scrollable, causing you to not see the header and footer no matter how slippery you are.\nSimilarly, 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.。\n\n\n## More\n- [Property Document](propertys_en.md) or [Api\u002FDoc](https:\u002F\u002Fpub.dev\u002Fdocumentation\u002Fpull_to_refresh\u002Flatest\u002Fpulltorefresh\u002FSmartRefresher-class.html)\n- [Custom Indicator](custom_indicator_en.md)\n- [Inner Attribute Of Indicators](indicator_attribute_en.md)\n- [Update Log](CHANGELOG.md)\n- [Notice](notice_en.md)\n- [FAQ](problems_en.md)\n\n\n## Exist Problems\n* about NestedScrollView,When you slide down and then slide up quickly, it will return back. The main reason is that\n NestedScrollView does not consider the problem of cross-border elasticity under\n bouncingScrollPhysics. Relevant flutter issues: 34316, 33367, 29264. This problem\n can only wait for flutter to fix this.\n* SmartRefresher does not have refresh injection into ScrollView under the subtree, that is, if you put AnimatedList or RecordableListView in the child\n is impossible. I have tried many ways to solve this problem and failed. Because of the\n 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\nComponent issues, such as AnimatedList, can't be used with AnimatedList and GridView unless\n I convert AnimatedList to SliverAnimatedList is the solution. At the moment,\n I have a temporary solution to this problem, but it's a bit cumbersome to rewrite the code inside it and then outside ScrollView.\nAdd SmartRefresher, see my two examples [Example 1](example\u002Flib\u002Fother\u002Frefresh_animatedlist.dart)和[Example 2](example\u002Flib\u002Fother\u002Frefresh_recordable_listview.dart)\n\n## Thanks\n\n[SmartRefreshLayout](https:\u002F\u002Fgithub.com\u002Fscwang90\u002FSmartRefreshLayout)\n\n## LICENSE\n\n\n```\n\nMIT License\n\nCopyright (c) 2018 Jpeng\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and\u002For sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n\n ```\n","flutter_pulltorefresh 是一个为 Flutter 滚动组件提供下拉刷新和上拉加载功能的插件。它支持几乎所有滚动组件，如 GridView 和 ListView，并且提供了全局设置默认指示器和属性的功能。此外，该插件还支持多种刷新样式、加载更多样式以及两级刷新等高级特性，同时兼容 Android 和 iOS 的默认滚动物理效果。适用于需要在移动应用中实现高效流畅的列表或网格数据动态加载与刷新场景。",2,"2026-06-11 03:21:40","top_language"]