{"id":13641250,"url":"https://github.com/lcodecorex/TwinklingRefreshLayout","last_synced_at":"2025-04-20T07:32:49.407Z","repository":{"id":211028639,"uuid":"52960120","full_name":"lcodecorex/TwinklingRefreshLayout","owner":"lcodecorex","description":"RefreshLayout that support for OverScroll and better than iOS.  支持下拉刷新和上拉加载的RefreshLayout,自带越界回弹效果，支持RecyclerView,AbsListView,ScrollView,WebView","archived":false,"fork":false,"pushed_at":"2023-03-27T03:44:19.000Z","size":82617,"stargazers_count":3998,"open_issues_count":114,"forks_count":672,"subscribers_count":95,"default_branch":"master","last_synced_at":"2024-10-29T15:27:52.935Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lcodecorex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-03-02T12:11:56.000Z","updated_at":"2024-10-28T02:16:32.000Z","dependencies_parsed_at":null,"dependency_job_id":"9759843a-01e7-4f28-8f98-3b8cae2750ce","html_url":"https://github.com/lcodecorex/TwinklingRefreshLayout","commit_stats":null,"previous_names":["lcodecorex/twinklingrefreshlayout"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lcodecorex%2FTwinklingRefreshLayout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lcodecorex%2FTwinklingRefreshLayout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lcodecorex%2FTwinklingRefreshLayout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lcodecorex%2FTwinklingRefreshLayout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lcodecorex","download_url":"https://codeload.github.com/lcodecorex/TwinklingRefreshLayout/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223057651,"owners_count":17080791,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T01:01:19.169Z","updated_at":"2025-04-20T07:32:49.400Z","avatar_url":"https://github.com/lcodecorex.png","language":"Java","readme":"## 【DECREEPTED】\n\n# TwinklingRefreshLayout\n[中文文档](./README_CN.md)\n\nTwinklingRefreshLayout extended the thoughts of SwipeRefreshLayout,using a ViewGroup to include a list of Views, to maintain its low coupling and high versatility. Follows are its main features.\n\n - New overscroll animations, running smoothly, much better than iOS.\n - Support RecyclerView, ScrollView, AbsListView, WebView and so on.\n - Support to load more.\n - Default support cross-border rebound.\n - You can open a pure bounds rebound mode.\n -  Lots of methods in the class OnRefreshListener.\n - It provides an interface to the callback during the sliding coefficient. Personalized offer good support.\n - NestedScroll,CoordinatorLayout\n\n **Any View is supported.**\n\n![](art/structure_v1.0.png)\n\n## Demo\n[Download Demo](art/app-debug.apk)\n\n![](art/gif_recyclerview.gif)  ![](art/gif_listview.gif)  ![](art/gif_gridview.gif) ![](art/gif_recyclerview2.gif) ![](art/gif_scrollview.gif)  ![](art/gif_webview.gif)\n\nYou can download these Videos for more details.\n\n- [Music - ListView - FixedHeader](art/gif_listview.mp4)\n- [Food - RecyclerView - PureScrollMode](art/gif_recyclerview.mp4)\n- [Science - GridView - SinaHeader](art/gif_gridview.mp4)\n- [Photo - RecyclerView - BezierLayout](art/gif_recyclerview2.mp4)\n- [Story - ScrollView - GoogleDotView](art/gif_scrollview.mp4)\n- [Dribbble - WebView - FloatRefresh](art/gif_webview.mp4)\n\n## Usage\n#### 1.Add a gradle dependency.\n```\ncompile 'com.lcodecorex:tkrefreshlayout:1.0.7'\n```\n\n#### 2.Add TwinklingRefreshLayout in the layout xml.\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003ccom.lcodecore.tkrefreshlayout.TwinklingRefreshLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/refreshLayout\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    app:tr_wave_height=\"180dp\"\n    app:tr_head_height=\"100dp\"\u003e\n\n    \u003candroid.support.v7.widget.RecyclerView\n        android:id=\"@+id/recyclerview\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:overScrollMode=\"never\"\n        android:background=\"#fff\" /\u003e\n\u003c/com.lcodecore.library.TwinklingRefreshLayout\u003e\n```\n\nTo get better effect, you'd better add code `android:overScrollMode=\"never\"` to the childView.\n\n#### 3.Coding in the Activity or Fragment.\n##### Change of state need to be manually controlled.\n```java\nrefreshLayout.setOnRefreshListener(new RefreshListenerAdapter(){\n            @Override\n            public void onRefresh(final TwinklingRefreshLayout refreshLayout) {\n                new Handler().postDelayed(new Runnable() {\n                    @Override\n                    public void run() {\n                        refreshLayout.finishRefreshing();\n                    }\n                },2000);\n            }\n\n            @Override\n            public void onLoadMore(final TwinklingRefreshLayout refreshLayout) {\n                new Handler().postDelayed(new Runnable() {\n                    @Override\n                    public void run() {\n                        refreshLayout.finishLoadmore();\n                    }\n                },2000);\n            }\n        });\n    }\n```\n\nUse finishRefreshing() method to end refresh, finishLoadmore() method to end load more. OnRefreshListener there are other methods, you can choose need to override.\n\nAnd if you want you refresh automatically, call the method startRefresh().\n\n##### setWaveHeight、setHeaderHeight、setBottomHeight、setOverScrollHeight\n- setMaxHeadHeight is used To set the maximum height of the head can be stretched.\n- setHeaderHeight is used to set the standard head height.\n- setMaxBottomHeight.\n- setBottomHeight is used to set the Bottom height.\n- setOverScrollHeight is used to set the max height of overscroll.\n\nAnd now dp value is supported.\n\n#### setEnableRefresh、setEnableLoadmore\nFlexible settings for whether to disable the pulling-down mode.\n\n##### setHeaderView(IHeaderView headerView)、setBottomView(IBottomView bottomView)\n\n#### setEnableOverScroll\nWhether to allow overscroll mode, opened by default.\n\n##### setOverScrollTopShow、setOverScrollBottomShow、setOverScrollRefreshShow\nWhether to allow the display refresh control on overscrolling, the default is true.\n\n##### setPureScrollModeOn()\nTo open the pure overscroll mode so that refreshView would gone permanently.\n\n##### setAutoLoadMore\nif open the loadmore mode after overscrolling bottom automatically.\n\n##### addFixedExHeader\nAllow you to add a view fixed on the top.\n\n##### startRefresh、startLoadMore、finishRefreshing、finishLoadmore\n\n##### setFloatRefresh(boolean)\nMake refresh-animation like SwipeRefreshLayout.\n\n##### setTargetView(View view)\nSet the target view that you can scroll.\n\n##### setDefaultHeader、setDefaultFooter\nstatic methods aims to set a default header/footer in a/an Application/Activity.\n\n#### 4.Attributes\n- tr_max_head_height - Flexible head height\n- tr_head_height -  Head height\n- tr_max_bottom_height\n- tr_bottom_height - Bottom height\n- tr_overscroll_height - OverScroll Height\n- tr_enable_refresh - default is true\n- tr_enable_loadmore - default is true\n- tr_pureScrollMode_on - default is false\n- tr_overscroll_top_show - default is true\n- tr_overscroll_bottom_show - default is true\n- tr_enable_overscroll - default is true.\n- tr_floatRefresh - open the float-refresh mode.\n- tr_autoLoadMore\n- tr_enable_keepIView - default is true.\n- tr_showRefreshingWhenOverScroll - default is true.\n- tr_showLoadingWhenOverScroll - default is true.\n\n## Other\n### 1.setOnRefreshListener\n- onPullingDown(TwinklingRefreshLayout refreshLayout, float fraction)  \n- onPullingUp(TwinklingRefreshLayout refreshLayout, float fraction)    \n- onPullDownReleasing(TwinklingRefreshLayout refreshLayout, float fraction)  \n- onPullUpReleasing(TwinklingRefreshLayout refreshLayout, float fraction)  \n- onRefresh(TwinklingRefreshLayout refreshLayout)  \n- onLoadMore(TwinklingRefreshLayout refreshLayout)  \n\nfraction = currentMoveHeight/headHeight OR (fraction = currentMoveHeight/bottomHeight).\n\n### 3.Header and Footer\n##### BezierLayout(pic 4)\n- setWaveColor\n- setRippleColor\n\n##### GoogleDotView(pic 5)\n##### SinaRefreshView(pic 3)\n- setArrowResource\n- setTextColor\n- setPullDownStr\n- setReleaseRefreshStr\n- setRefreshingStr\n\n##### ProgressLayout(SwipeRefreshLayout pic 6)\n- setProgressBackgroundColorSchemeResource(@ColorRes int colorRes)\n- setProgressBackgroundColorSchemeColor(@ColorInt int color)\n- setColorSchemeResources(@ColorRes int... colorResIds)\n\n####Footer\n##### BallPulseView(pic 2)\n- setNormalColor(@ColorInt int color)\n- setAnimatingColor(@ColorInt int color)\n\n##### LoadingView(pic 3)\nHere is more animations.[AVLoadingIndicatorView](https://github.com/81813780/AVLoadingIndicatorView)。\n\n### 3.Personalize the Header and Footer.\nThe Header needs to implement IHeaderView interface and Footer in in the same way(IBottomView).\n```java\npublic interface IHeaderView {\n    View getView();\n\n    void onPullingDown(float fraction,float maxHeadHeight,float headHeight);\n\n    void onPullReleasing(float fraction,float maxHeadHeight,float headHeight);\n\n    void startAnim(float maxHeadHeight,float headHeight);\n\n    void reset();\n}\n```\n\ngetView() method is not allow to return null.\n\n#### Let's implement a simple refresh dynamic efficiency.\n1.Define SinaRefreshHeader extended from FrameLayout and implement IHeaderView interface.\n\n2.Return this in the method getView().\n\n3.Inflate and find Views in the layout xml.\n\n```java\nvoid init() {\n        if (rootView == null) {\n            rootView = View.inflate(getContext(), R.layout.view_sinaheader, null);\n            refreshArrow = (ImageView) rootView.findViewById(R.id.iv_arrow);\n            refreshTextView = (TextView) rootView.findViewById(R.id.tv);\n            loadingView = (ImageView) rootView.findViewById(R.id.iv_loading);\n            addView(rootView);\n        }\n    }\n```\n\n4.Override some methods.\n```java\n@Override\n    public void onPullingDown(float fraction, float maxHeadHeight, float headHeight) {\n        if (fraction \u003c 1f) refreshTextView.setText(pullDownStr);\n        if (fraction \u003e 1f) refreshTextView.setText(releaseRefreshStr);\n        refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180);\n\n\n    }\n\n    @Override\n    public void onPullReleasing(float fraction, float maxHeadHeight, float headHeight) {\n        if (fraction \u003c 1f) {\n            refreshTextView.setText(pullDownStr);\n            refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180);\n            if (refreshArrow.getVisibility() == GONE) {\n                refreshArrow.setVisibility(VISIBLE);\n                loadingView.setVisibility(GONE);\n            }\n        }\n    }\n\n    @Override\n    public void startAnim(float maxHeadHeight, float headHeight) {\n        refreshTextView.setText(refreshingStr);\n        refreshArrow.setVisibility(GONE);\n        loadingView.setVisibility(VISIBLE);\n    }\n\n    @Override\n    public void onFinish(OnAnimEndListener listener) {\n    listener.onAnimEnd();\n    }\n```\n\n5.layout xml.\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cLinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"horizontal\" android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:gravity=\"center\"\u003e\n    \u003cImageView\n        android:id=\"@+id/iv_arrow\"\n        android:layout_width=\"24dp\"\n        android:layout_height=\"24dp\"\n        android:src=\"@drawable/ic_arrow\"/\u003e\n\n    \u003cImageView\n        android:id=\"@+id/iv_loading\"\n        android:visibility=\"gone\"\n        android:layout_width=\"34dp\"\n        android:layout_height=\"34dp\"\n        android:src=\"@drawable/anim_loading_view\"/\u003e\n\n    \u003cTextView\n        android:id=\"@+id/tv\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginLeft=\"16dp\"\n        android:textSize=\"16sp\"\n        android:text=\"pull down to refresh\"/\u003e\n\u003c/LinearLayout\u003e\n```\n\nPay attention to the using of the parameter `fraction`. Such as the code above`refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180)`，`fraction * headHeight` is the translationY of the Head and 180 is the angle the arrow would rotate，so that we can make the arrow rotate 180 degrees when the translationY is come to the maxHeadHeight.\n\n\nonPullingDown/onPullingUp\nonPullReleasing\nstartAnim - be called automatically after the method onRefresh/onLoadMore is called.\n\nCongratulations! Simple to use and simple to Personalise.（To see a more simple example. **TextHeaderView(pic 4)**）。\n\n### NestedScroll\n#### TwinklingRefreshLayout Nested CoordinatorLayout\n---layout\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003ccom.lcodecore.tkrefreshlayout.TwinklingRefreshLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/refresh\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\u003e\n\n    \u003candroid.support.design.widget.CoordinatorLayout\n        android:id=\"@+id/coord_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:addStatesFromChildren=\"true\"\n        android:fitsSystemWindows=\"true\"\u003e\n\n        \u003candroid.support.design.widget.AppBarLayout\n            android:id=\"@+id/appbar_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:clipChildren=\"false\"\u003e\n\n            \u003c!--...--\u003e\n\n        \u003c/android.support.design.widget.AppBarLayout\u003e\n\n        \u003candroid.support.v7.widget.RecyclerView\n            android:id=\"@+id/recyclerview\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\" /\u003e\n\n    \u003c/android.support.design.widget.CoordinatorLayout\u003e\n\u003c/com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout\u003e\n```\n\n--- code1\n```\nrefreshLayout.setTargetView(rv);\n```\nFind the RecyclerView/ListView.\n\n--- code2\n```java\nAppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar_layout);\nappBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {\n    @Override\n    public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {\n        if (verticalOffset \u003e= 0) {\n            refreshLayout.setEnableRefresh(true);\n            refreshLayout.setEnableOverScroll(false);\n        } else {\n            refreshLayout.setEnableRefresh(false);\n            refreshLayout.setEnableOverScroll(false);\n        }\n    }\n});\n```\n\n####CoordinatorLayout nested TwinklingRefreshLayout\n--- layout\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003candroid.support.design.widget.CoordinatorLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/coord_container\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:addStatesFromChildren=\"true\"\n    android:fitsSystemWindows=\"true\"\u003e\n\n    \u003ccom.lcodecore.tkrefreshlayout.TwinklingRefreshLayout\n        android:id=\"@+id/refresh\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\u003e\n\n        \u003candroid.support.v7.widget.RecyclerView\n            android:id=\"@+id/recyclerview\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\" /\u003e\n\n    \u003c/com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout\u003e\n\n\u003c/android.support.design.widget.CoordinatorLayout\u003e\n```\nPay attention to `layout_behavior=\"@string/appbar_scrolling_view_behavior\"` for TwinklingRefreshLayout.\n\n\u003e ps：Contact me: lcodecore@163.com\n\u003e QQ group: 202640706\n\nIf you like this library, you can donate me. Buy me a coffee!\n\n![](art/alipay.jpg) ![](art/wepay.png)\n\n## Update Logs\n#### v1.07\n- NestedScroll,CoordinateLayout\n- Any View\n- Keep state when refreshing/loading.\n\n#### v1.06\n- Repair memory leaks of customized Views.\n- remove the dependence of AVLoadingIndicatorView.\n- Fix bugs of OverScroll when TargetView scrolls at the top/bottom.\n- Repair bugs of touching,scroll-event listeners.\n- Optimization of interface flicker problems after load-more.\n\n#### v1.05 Emergency Fix\n- Fix the bug of setAutoLoadMore().\n- Fix the bug that FixedHeader covered the first item of listview.\n- Add onRefreshCanceled()/onLoadmoreCanceled() for RefreshListenerAdapter.\n\n#### v1.04\n- Refactor the code.\n- Make animations smoothly.\n- Add support to Fixed Header.\n- Add support to float refresh mode.\n- IHeadView.onFinish(animEndListener) -\u003e Available to run animations before finishRefresh.\n\n#### v1.03\n- more attributes.\n- Fix the NullPointerException bug in Fragment.\n- Fix the Sliding conflict.\n\n\nLicense\n-------\n\n    Copyright 2016 lcodecorex\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n","funding_links":[],"categories":["下拉刷新"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flcodecorex%2FTwinklingRefreshLayout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flcodecorex%2FTwinklingRefreshLayout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flcodecorex%2FTwinklingRefreshLayout/lists"}