How to use SwipeRefreshLayout the right way
In the latest revision of the android support library came out with an interesting new layout :SwipeRefreshLayout which implements the famous pull-down-to-refresh pattern. In the following i will show you how to implement it with a ListView and avoid some pitfalls.
To use this new layout you will need to have at least the android support library with at least revision 19.1
First we need to import the support library project to our workspace and then add it to your main project as a library.
Then we will start by defining our SwipeToRefresh container
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| <?xml version= "1.0" encoding= "utf-8" ?> <android.support.v4.widget.SwipeRefreshLayout xmlns:android= "http://schemas.android.com/apk/res/android" android:id= "@+id/swipe_container" android:layout_width= "match_parent" android:layout_height= "match_parent" > <LinearLayout android:layout_width= "match_parent" android:layout_height= "match_parent" android:orientation= "vertical" > <ListView android:id= "@id/android:list" android:layout_width= "match_parent" android:layout_height= "0dp" android:layout_weight= "1" android:drawSelectorOnTop= "false" /> </LinearLayout> </android.support.v4.widget.SwipeRefreshLayout> |
and then in our activity or fragment we load the layout and set it up
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
| private SwipeRefreshLayout swipeRefreshLayout; private Handler handler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ArrayAdapter<String> adapter = new ArrayAdapter<String>( this , android.R.layout.simple_list_item_1, getCountries()); ListView listView = (ListView) findViewById(R.id.listView); listView.setAdapter(adapter); // find the layout swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container); // the refresh listner. this would be called when the layout is pulled down swipeRefreshLayout.setOnRefreshListener( new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { // get the new data from you data source // TODO : request data here // our swipeRefreshLayout needs to be notified when the data is returned in order for it to stop the animation handler.post(refreshing); } }); // sets the colors used in the refresh animation swipeRefreshLayout.setColorSchemeResources(R.color.blue_bright, R.color.green_light, R.color.orange_light, R.color.red_light); } private final Runnable refreshing = new Runnable(){ public void run(){ try { // TODO : isRefreshing should be attached to your data request status if (isRefreshing()){ // re run the verification after 1 second handler.postDelayed( this , 1000); } else { // stop the animation after the data is fully loaded swipeRefreshLayout.setRefreshing( false ); // TODO : update your list with the new data } } catch (Exception e) { e.printStackTrace(); } } }; |
For now if you try to swipe down to refresh your will be able to see the animation and your list would be updated. However, if scroll down in your list and try to go up again the swipe to refresh would be triggered again and you won’t be able to go back to the top of your list.
Obviously, this would be very annoying and the trick would be forcing the layout to refresh only when the very first item of the list is fully visible. To do this we assign anOnScrollListener to our ListView after the initialization of our swipe to refresh layout
Obviously, this would be very annoying and the trick would be forcing the layout to refresh only when the very first item of the list is fully visible. To do this we assign anOnScrollListener to our ListView after the initialization of our swipe to refresh layout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| listView.setOnScrollListener( new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { boolean enable = false ; if (listView != null && listView.getChildCount() > 0){ // check if the first item of the list is visible boolean firstItemVisible = listView.getFirstVisiblePosition() == 0; // check if the top of the first item is visible boolean topOfFirstItemVisible = listView.getChildAt(0).getTop() == 0; // enabling or disabling the refresh layout enable = firstItemVisible && topOfFirstItemVisible; } swipeRefreshLayout.setEnabled(enable); } }); |
Now you are good to go!
from : https://yassirh.com
No comments: