BGARefreshLayout-Android: A Java Pull-to-Refresh Library With Four Header Styles
多种下拉刷新效果、上拉加载更多、可配置自定义头部广告位
At a glance
- What is it?
- BGARefreshLayout-Android wraps any Android view with pull-to-refresh, pull-up loading and an optional custom banner header. It is a Java library for teams maintaining older View-based screens, and its README lists several unfixed layout problems.
- Who is it for?
- Adopt BGARefreshLayout-Android if you maintain a View-based Android app, want a Sina Weibo, MOOC, Meituan or sticky QQ-style header without writing the pull gesture yourself, and can live with the layout problems the README lists. Do not adopt it for a Compose-only codebase or for a screen where the loading-more view must track the user's scroll while a request is in flight.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 81 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What BGARefreshLayout-Android Adds to a Plain View Hierarchy
Android's own pull-to-refresh widget covers the refresh gesture. BGARefreshLayout-Android covers the gesture and the footer. The README describes a single layout container that wraps any child view and supplies both a refresh header and a load-more footer, with the footer's background, background drawable, and status text all settable at runtime. That is the gap it fills: one wrapper for the top and bottom of a list, rather than two separate widgets configured independently.
The audience is narrow and identifiable. This is Java, it is built around View-based screens, and the README's own example extends AppCompatActivity and implements a delegate interface. If your screens are Fragments or Activities holding a RecyclerView, a ListView, or a ScrollView, this fits. If your project is Kotlin and Compose throughout, the delegate interface and the XML wrapper have no place to sit.
The custom header slot is the least common part. The README shows setCustomHeaderView taking a view and a boolean that controls whether load-more stays available. That lets a banner or ad slot live above the list, inside the same scroll container, which is a layout most apps end up hand-rolling.
The Delegate Interface and the ViewHolder Subclass Are the Whole Architecture
There is no service, no plugin, no background thread. The mechanism is two extension points plus a wrapper view.
First, the host Activity or Fragment implements BGARefreshLayout.BGARefreshLayoutDelegate. The README shows onBGARefreshLayoutBeginRefreshing as the callback fired when the pull passes the trigger threshold. The host loads data and then calls endRefreshing on the layout to retract the header. There is a matching callback for load-more, shown truncated in the README as onBGARefres.
Second, a refresh style is a subclass of the abstract class BGARefreshViewHolder. The README names four concrete implementations shipped with the library: BGAMoocStyleRefreshViewHolder, BGANormalRefreshViewHolder, BGAStickinessRefreshViewHolder, and BGAMeiTuanRefreshViewHolder. The README states that a developer can extend the abstract class and implement methods such as handleScale(float scale, int moveYDistance) to drive a custom animation from the pull distance.
So the data flow is: the wrapper measures the drag, the ViewHolder turns that measurement into visuals, the delegate tells your code a refresh started, and your code tells the wrapper when to stop. Everything runs on the UI thread, which is why the README's sample wraps its fake network delay in an AsyncTask and calls endRefreshing from onPostExecute.
Installing BGARefreshLayout-Android Through JitPack
The README gives JitPack as the distribution channel. Add the JitPack repository to the root build.gradle, then declare the dependency in the app module. The version string is not fixed in the README: it says to read the version name from the JitPack badge on the project page and substitute it yourself. Do not copy a version number from anywhere else.
dependencies {
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.github.bingoogolapple:BGARefreshLayout-Android:latestVersion'
}After the dependency resolves, wrap the content view in the layout file. The README is emphatic about one detail, and it is the single most common cause of a missing load-more footer: the direct child must use layout_height="0dp" with layout_weight="1".
<cn.bingoogolapple.refreshlayout.BGARefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_modulename_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<AnyView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</cn.bingoogolapple.refreshlayout.BGARefreshLayout>Then wire it in code. The README's example finds the view, sets the delegate, constructs a ViewHolder subclass, and hands that ViewHolder to the layout. The README writes the ViewHolder construction as XXXImplRefreshViewHolder, a placeholder for whichever of the four styles you pick.
mRefreshLayout = (BGARefreshLayout) findViewById(R.id.rl_modulename_refresh);
mRefreshLayout.setDelegate(this);
BGARefreshViewHolder refreshViewHolder = new XXXImplRefreshViewHolder(this, true);
mRefreshLayout.setRefreshViewHolder(refreshViewHolder);The second constructor argument is documented as whether load-more is enabled. From there, the optional setters cover the loading-more text, the footer background colour resource, the footer background drawable resource, and the same two for the refresh header. The README also shows setCustomHeaderView(mBanner, false) for a banner above the list.
One placement rule comes with a warning rather than a code sample: if the layout lives in a Fragment, initialise it in onCreateView, not in onActivityCreated.
Problems the README Admits To
The README has a section titled, in translation, currently existing problems, and it lists three. They are worth reading before you commit, because two of them are visible to users.
The first: when the custom header banner is configured as scrollable, the transition between the content area and the banner is not smooth. That is the banner feature's own limitation, not an edge case.
The second: when a RecyclerView or AbsListView sits inside BGAStickyNavLayout and the last item of the first page lands exactly at the bottom, the load-more view floats on top of that item. This is a visual defect in a specific but reachable scroll position.
The third: while a refresh or load-more is in progress, the user's vertical scrolling does not move the refresh header or the load-more footer with it. The README states this plainly. If your design expects the header to follow the finger during the loading state, this library does not do that.
The README also flags the sticky QQ-style header directly: the cubic Bezier curve is described as not well tuned, and the effect at the start of the pull is described as not good. That is the author's own assessment of a shipped style.
Finally, the README's own FAQ exists because the load-more view sometimes does not appear. Both answers are configuration rules, which tells you the failure mode is common enough to document.
BGARefreshLayout-Android Versus SwipeRefreshLayout
The obvious alternative is Android's own SwipeRefreshLayout, which is what the related search terms mostly point at. The difference is scope, not quality.
SwipeRefreshLayout does the top gesture and nothing else. It has no footer, no load-more callback, no notion of a refresh style you swap out. If you use it, pull-up loading is your problem: you detect the scroll position yourself, show your own footer, and manage its visibility across pagination states. That is more code, but it is code you control, and it lives in the same AndroidX world as everything else in a modern app.
BGARefreshLayout-Android trades that control for a packaged footer and four ready-made header animations, one of which is a sticky QQ-style effect that SwipeRefreshLayout has no equivalent for. It also gives you the banner slot inside the scroll container, which is genuinely awkward to build on top of SwipeRefreshLayout without fighting the nested scroll.
The trade is that you inherit the three problems above and you depend on a JitPack artifact rather than an AndroidX one. If your screens are simple lists where a spinner is enough, SwipeRefreshLayout is the smaller commitment. If the header animation is part of your product's look, the four styles here are the reason to pick this library.
Maintenance, Licence and Upgrade Cost
The repository is not archived, and the last push was on 2026-07-11. The published releases, however, are old: v1.0.1, v1.0.2 and v1.0.3 all landed on 2015-06-14. The README does not explain the gap between repository activity and release tags, and it does not document a migration path between versions. If you pin a JitPack version, treat the pin as permanent until you verify what changed.
Licence is a genuine unknown here. The README carries an Apache 2.0 badge linking to apache.org, but the repository metadata shows no licence field. Those two signals disagree. Anyone shipping this in a commercial app should read the LICENSE file in the repository, if one exists, rather than trusting a badge. This is not legal advice, and the badge is not a substitute for the actual file.
The upgrade cost is structural rather than version-to-version. The library depends on androidx.legacy:legacy-support-v4:1.0.0 and androidx.recyclerview:recyclerview:1.0.0 in the README's own example, which pins you to an older support surface. A project that has moved past those artifacts will need to reconcile the dependency graph before the first build succeeds. The README does not document rollback, so plan to verify the integration on a branch.
Editorial conclusion
Adopt BGARefreshLayout-Android if you maintain a View-based Android app, want a Sina Weibo, MOOC, Meituan or sticky QQ-style header without writing the pull gesture yourself, and can live with the layout problems the README lists. Do not adopt it for a Compose-only codebase or for a screen where the loading-more view must track the user's scroll while a request is in flight. Before wiring it in, check the JitPack badge for the current version string, confirm the library resolves against your AndroidX setup, and reproduce the sticky-nav case with a RecyclerView whose first-page last item sits at the bottom.
Frequently asked questions
Can I build a custom pull-to-refresh animation with BGARefreshLayout-Android?
Yes. The README states that you can extend the abstract class BGARefreshViewHolder and implement methods such as handleScale(float scale, int moveYDistance) to drive your own animation, and points to the four shipped ViewHolder subclasses as references.
Which refresh styles does BGARefreshLayout-Android ship with?
The README lists four: a Sina Weibo style, a MOOC style, a Meituan style, and a sticky QQ-friend-list style. Each allows you to set the background of the whole refresh header, and the MOOC and Meituan styles allow replacing their logo or image and colours.
Is BGARefreshLayout-Android still released?
The repository is not archived and the last push was on 2026-07-11, but the most recent published releases are v1.0.1, v1.0.2 and v1.0.3, all dated 2015-06-14. The README does not describe a release process or a changelog policy.
What licence does BGARefreshLayout-Android use?
The README shows an Apache 2.0 badge, but the repository metadata does not list a licence. Check the actual licence file in the repository before relying on the badge.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/bingoogolapple-bgarefreshlayout-android)