EventBus

android-public-transport-apps

Envie de passer une information entre différents fragments ? Ou simplement indiquer depuis une activité à un fragment qu’il doit se rafraichir ? Oubliez les anciennes méthodes un peu bancales, faites place à EventBus !

 

EventBus fonctionne de la manière suivante, si nous voulons envoyer un message de la classe A vers la classe B :

  1. B s’enregistre en tant que receveur auprès d’EventBus
  2. A envoie le message à EventBus
  3. EventBus le transmet à B

EventBus-Publish-SubscribeImporter EventBus

Comme toute librairie, il suffit de l’inclure dans le fichier build.gradle de votre application

build.gradle

compile 'de.greenrobot:eventbus:2.4.0'

Déclarer un événement

Première étape pour utiliser EventBus : créer nos évènements, les messages qui vont être envoyés par EventBus. Imaginons le cas suivant : je veux demander à un Fragment d’afficher “Refresh”, et ce depuis mon Activité. Je vais créer un objet PleaseRefreshEvent (on peux lui donner le nom que l’on veux).

PleaseRefreshEvent.java

public class PleaseRefreshEvent{
}

Lancer un événement

Depuis n’importe quel endroit de votre code, vous pouvez transmettre un événement :

EventBus.getDefault().post(new PleaseRefreshEvent());

Vous voyez qu’il suffit de lui passer un new PleaseRefreshEvent()

Recevoir un évènement

S’enregistrer auprès d’EventBus

Penser à enregistrer l’objet destination en temps que receveur auprès d’EventBus, en prenant en compte le cycle de vie de l’activité ou du fragment.
Dans le onStart() on s’enregistre auprès d’EventBus, puis on n’oublie pas de se désinscrire lors du onStop().

public class MyFragment extends Fragment{

    @Override
    public void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }
    @Override
    public void onStop() {
        super.onStop();
        EventBus.getDefault().unregister(this);
    }

}

Recevoir un événement

Il suffit maintenant d’ajouter une fonction void onEvent(NOM_EVENT event) à notre classe, ce qui donne pour un PleaseRefreshEvent


public class MyFragment extends Fragment{

    @Override
    public void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }
    @Override
    public void onStop() {
        super.onStop();
        EventBus.getDefault().unregister(this);
    }

    public void onEvent(PleaseRefreshEvent event){
         //votre action
    }

}

eventbus-for-android-7-638

Exemple complet

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().post(new PleaseRefreshEvent());
            }
        });
    }

}

layout/activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/please_refresh"/>

    <fragment
        android:id="@+id/myFragment"
        android:name="com.tutosandroidfrance.eventbussample.fragment.MyFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

J’ai choisi ici d’ajouter le fragment directement depuis le layout, afin de le rendre transparent depuis le code Java de l’activité.

L’activité contiendra donc à son lancement le fragment MyFragment.

MyFragment.java

public class MyFragment extends Fragment{

    TextView textView;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment,container,false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        textView = (TextView) view.findViewById(R.id.text);
    }

    @Override
    public void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }

    @Override
    public void onStop() {
        super.onStop();
        EventBus.getDefault().unregister(this);
    }

    //This object can receive a PleaseRefreshEvent
    public void onEvent(PleaseRefreshEvent event){
        textView.setText(getString(R.string.refresh));
    }
}

layout/fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/text"
        android:text="@string/question"
        android:layout_gravity="center"/>

</FrameLayout>

Voici le résultat, au click du bouton, le contenu du Fragment se met à jour :

device-2015-06-23-174051device-2015-06-23-174259

 

Extras

Petite astuce, il est possible de transmettre des données avec notre évènement, pour cela il suffit d’ajouter des propriétés à notre événement :

public class PleaseRefreshEvent{

	private String myString;

	public PleaseRefreshEvent(String myString){
		this.myString = myString;
	}

	public String getMyString(){
		return myString;
	}
}

Vous pouvez ensuite l’envoyer de la manière suivante :

EventBus.getDefault().post(new PleaseRefreshEvent("toto"));

Et utiliser les paramètres depuis le onEvent :

public void onEvent(PleaseRefreshEvent event){
        textView.setText(event.getMyString());
}

Vous n’avez plus aucune excuse pour ne pas utiliser cette fabuleuse librairie 🙂

Les sources de ce tuto sont disponibles sur gihub

4 commentaire sur “EventBus

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *