Ajouter un Pull To Refresh avec SwipeRefreshLayout
Envie d’ajouter un effet Pull To Refresh à votre ListView ? Et bien sachez qu’il existe un composant natif à Android permettant d’ajouter cette fonctionnalité !
Pour ceux qui ignore ce qu’est un Pull To Refresh, je vais vous le montrer en image :
Il s’agit donc d’ajouter un événement à notre ListView, qui s’active lorsque l’utilisateur est en haut de la liste mais continue à scroller vers le bas.
Android Support V4
Avant de commencer à vous parler de cette vue, il faut que j’introduise une notion en Android : le support.
Comme vous pouvez le savoir, il existe une multitude de versions d’android, et à l’heure où je vous parle nous sommes sur Android Lolipop, qui est la 5ème édition d’Android. Chaque version apporte son lot de nouveautés, de vues et d’outils, embarqués dans sa nouvelle version du système d’exploitation installé sur nos smartphones. Le problème est qu’il est fréquent de devoir réaliser une application supportant plusieurs version (par exemple supporter android à partir de 2.3).
En plus d’ajouter ces composants dans les nouvelles versions d’Android, la firme les publie aussi dans des paquets nommés Support, qui ont pour role d’utiliser le composant système s’il est présent, ou de reproduire son comportement (il est donc embarqué dans cette librairie). Certains oseront dire que ça alourdit l’application, répondez leur que rien ne leur empêche de développer leur application en ne supportant que la dernière version d’Android, et donc de perdre la moitié des utilisateurs 😉
Utilisation
Nous allons donc commencer par importer cette librairie via Gradle :
compile 'com.android.support:support-v4:21.0.3'
L’utilisation se fait ensuite en 2 étapes, une partie dans le layout de notre écran, le reste dans notre code Java.
Je ne détaillerai pas comment se servir des ListView dans ce tutoriel, cependant vous pouvez regarder le précédent article consacré à ce sujet : https://tutos-android-france.com/listview-afficher-une-liste-delements/
Layout
Partons d’un Layout simple, ne contenant qu’une ListView :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
Afin d’ajouter la fonctionnalité de Pull To Refresh, il suffit juste de placer notre ListView dans un objet nommé SwipeRefreshLayout. Comme dit précédemment, cet objet est inclu dans la librairie Support V4, nous devons donc l’utiliser avec son préfixe complet android.support.v4.widget.SwipeRefreshLayout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipeRefreshLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.v4.widget.SwipeRefreshLayout> </RelativeLayout>
Ajoutez un adapter qui affiche des Strings pour visualiser plus facilement.
public class MainActivity extends ActionBarActivity { List<String> strings = new ArrayList<String>(); ListView mListView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mListView = (ListView) findViewById(R.id.listView); for(int i=0;i<20;++i) strings.add("Element "+i); ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, strings); mListView.setAdapter(adapter); } }
Vous pouvez dès à présent essayer ce composant en compilant l’application et en le lançant sur votre smartphone.
Java
Vous aurez pu remarquer en testant le SwipeRefreshLayout qu’une fois cet element relâché, il tourne indéfiniment. En effet il faut qu’un contrôleur lui indique qu’il a finit de rafraichir le contenu de la ListView qu’il contient.
Comme toute vue, nous pouvons le récupérer notre avec son identifiant, avec la méthode findViewById
public class MainActivity extends ActionBarActivity { List<String> strings = new ArrayList<String>(); ListView mListView; SwipeRefreshLayout mSwipeRefreshLayout; ArrayAdapter<String> mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mListView = (ListView) findViewById(R.id.listView); mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout); for(int i=0;i<20;++i) strings.add("Element "+i); mAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, strings); mListView.setAdapter(mAdapter); } }
Si nous regardons à la documentation officielle de cette vue, nous pouvons remarquer qu’elle possède les méthodes suivantes :
- setColorSchemeColors(int… colors) : permet de modifier la couleur de la flèche qui tourne
- setProgressBackgroundColor(int color) : permet de modifier la couleur de fond du cercle
- setSize(int size) : permet de modifier la taille de notre flèche (DEFAULT ou LARGE)
Ces méthodes sont utilisées afin de modifier l’aspect de notre élément, mais intéressons nous plutôt au coté fonctionnel :
- setRefreshing(true) : permet de lancer l’animation de mise à jour.
- setRefreshing(false) : indique à la vue que le contenu de la ListView à été mise à jour
- setOnRefreshListener(OnRefreshListener) : récupère les évènements lancés par notre SwipeRefreshLayout. Utilisé par notre Activity afin de savoir que l’utilisateur a effectué un SwipeToRefresh
Implémentons donc le OnRefreshListener dans notre Activity :
mSwipeRefreshLayout.setOnRefreshListener(this);
@Override public void onRefresh() { //appellé lors de l'action Pull To Refresh }
Je vais donc simuler une méthode longue comme un appel réseau qui aurait duré 2 secondes, ensuite ajouter des éléments à ma ListView puis indiquer à mon SwipeRefreshLayout que le la mise à jour a été effectuée . (Pour les puristes Android, il est préférable d’utiliser des AsyncTask)
Je vais simplement utiliser ici une méthode des vues nommée .PostDelayed(Runnable runnable, int delay) qui permet d’effectuer une action après delay millisecondes.
public class MainActivity extends ActionBarActivity implements SwipeRefreshLayout.OnRefreshListener { List<String> strings = new ArrayList<String>(); ListView mListView; SwipeRefreshLayout mSwipeRefreshLayout; ArrayAdapter<String> mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mListView = (ListView) findViewById(R.id.listView); mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout); mSwipeRefreshLayout.setOnRefreshListener(this); for(int i=0;i<20;++i) strings.add("Element "+i); mAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, strings); mListView.setAdapter(mAdapter); } @Override public void onRefresh() { //appellé lors de l'action Pull To Refresh mSwipeRefreshLayout.postDelayed(new Runnable() { @Override public void run() { //appellé après 2000 ms //vide la liste strings.clear(); //puis ajoute les nouveaux elements for(int i=0;i<20;++i) strings.add("NouvelElement "+i); //annonce à l'adapter que les données ont changés mAdapter.notifyDataSetChanged(); //avertie le SwipeRefreshLayout que la mise à jour a été effectuée mSwipeRefreshLayout.setRefreshing(false); } },2000); } }
[embedyt]https://www.youtube.com/watch?v=xPVYsWEMaRU[/embedyt]
Merci pour toutes ces infos, voici une bonne lecture. J’ai appris différentes choses en vous lisant, merci à vous. Bonne journée à tout le monde ! Fabienne Huillet neonmag.fr
I will immediately grab your rss feed as I can not find your email subscription link or enewsletter service. Do you’ve any? Please let me know in order that I could subscribe. Thanks. gafkdcbfedkd
Very interesting topic, appreciate it for putting up. kedggcecgegbkcaf
Article fort sympathique, une lecture agréable. Ce blog est vraiment pas mal, et les sujets présents plutôt bons dans l’ensemble, bravo ! Virginie Brossard