Working pull to refresh

This is a story about how the working implementation of Pull to refresh for Android turned out. There will be no code examples at all. A few pictures and at the end of the article a link to the project archive.

Recently there was a need to embed Pull to refresh in the current application. This is now fashionable, users are used to it, and has become the standard for twitter clients. The search for ready-made solutions on the network led to the only option - the open-source project Johan Nilsson android-pulltorefresh on Github.





A Header is inserted into the ListView, which is hidden if necessary. The solution is working, but very crooked. Often freezes in some state. If there are few elements in the list and they do not occupy all the space allotted for the ListView, then the Header is not hidden, and the inscription changes to Tap to refresh. The logical limitation of this implementation. Another feature was discovered when adding this project to a working application. Since Pull to refresh is a Header, the setSelection (1) method is often executed to hide the Header. And since we use saving and restoring the position, of course the constant call to setSelection spoils everything.

At first, they decided to finalize this implementation, to fix the most unpleasant moments. Even built into one project. But I didn’t succeed in doing as I wanted, the restrictions on the use of Header affected.

There was an idea how to do it differently and free time appeared. Since the problem is in the Header, it means that you need to remove it and put the Pull to refresh View and ListView itself in one LinearLayout and move it. Ideally, I wanted to get the same Pull to refresh as in the official Twitter client. But another bunch is used there. Pull to refresh is smooth there and works well everywhere. In general, we spent a lot of time watching the work of the official Twitter client.

There are many options for what and how to move. You can move both Pull to refresh View, and ListView, and LinearLayout. You can move by changing Padding, Margin or ScrollTo. After a large number of experiments on the emulator and on real devices, the most optimal combination was found. The initial shift is made by changing the Padding to the height of the Pull to refresh View, so we hide it from the screen. And then we move the entire Layout by changing ScrollTo.

It turned out beautifully and as smoothly as possible. But a problem arose, at that time seeming insurmountable. For some reason, when shifting the Layout, everything started to jump. The coordinates came either lower or higher, and there was no way to fix it. We almost returned to the original plan - to finalize Pull to refresh by Johan Nilsson.

But then, as if by magic, another project came to my eyes. Alternative Pull To Refresh from guillep on the same Github. It works even worse than Johan Nilsson, but uses a completely different mechanism similar to our idea. And most importantly, there is a problem with the jumping Layout. The last three coordinates are taken and the average is calculated. Thus, smoothness is ensured.



We took a little from each project, combined everything, and we got a well-working Pull to refresh, but the loading state remained unfinished. After release, Release to refresh turns into Loading and in this state it should scroll along with the list, so it should be part of the ListView. A separate Pull to refresh View should disappear, and a Pull to refresh View in the Loading state should be added to the ListView.

Since our View must constantly appear and disappear in the ListView, you cannot use it as a Header. But I do not want to change the current adapters either. It is necessary that when adding Pull to refresh to the working project, there should be as few changes as possible. We decided to use a special Adapter inside Pull to refresh as a Decorator. And this adapter controls the availability of a special View in the Loading state.



There were a lot of problems, especially when adding to a working draft, but all of them were successfully resolved. In the end, it turned out to be a class that can replace the usual ListView and which implements the well-functioning Pull to refresh. It works great on all APIs starting with version 1.5.

Only on some Samsung devices with a redesigned ListView are there occasional problems. But there are already ideas how and what can be redone.

Project on GitHub .

Also popular now: