Eventex, Android Express Events

Android library to exchange messages between Fragments, ViewGroups, Activity. No need to create interfaces and pass listeners to multiple classes. There is also no need to subscribe/unsubscribe for events!

Simple

To post message

new UIEvent("button.ok.click").post(view); // yes, this is it

To receive message. In any class that extends Fragment, ViewGroup, or Activity

public class CustomFragment extends Fragment implements UIEventListener {
//  .....
    @Override
    public boolean onMessage(@NonNull UIEvent uiEvent) {
        switch (uiEvent.what) {
            case "button.ok.click":
                Log.d(uiEvent.toString());
                return true; // to stop message propagation
        }
        return false;   // to let other objects to process message
    }
}

Much less boilerplate code compare to classic solution
Communicate with other fragments!
Class CustomFragment extends Android class Fragment. It will also
work well if the class extends Activity, ViewGroup, or any layout
derived from ViewGroup (LinearLayout, FrameLayout, etc..)

Features

  • Delivers messages between UI components of an Activity.
  • Supports synchronous and asynchronous communication.
  • No need to subscribe/unsubscribe to receive messages.
  • Completely decouples components.
  • No reflection and no ProGuard rules.
  • Tiny code size.

Requirements

  • Android 4.1.0(API 16) or above.
  • Java 8

Prerequisites

Make sure Java 8 (1.8) support is enabled in the gradle file

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

Add EventEx to the project gradle file (Androidx based projects)

implementation 'dev.uchitel:eventex:1.0.0'

Or for Android Support Library projects

implementation 'dev.uchitel:eventex-support:1.0.0'

More Details

Message can be sent synchronously

new UIEvent(12345).send(viewGroup);

Message can carry additional integer and string value:

new UIEvent(12345)
    .setText("some text to pass with message")
    .setNumber(9876) // some integer to pass with message
    .post(viewGroup);

Next code will properly receive this message:

public class FragmentReceiver extends Fragment implements UIEventListener {
//  .....
    @Override
    public boolean onMessage(@NonNull UIEvent uiEvent) {
        switch (uiEvent.code) {
            case 12345:
                Log.d("FragmentReceiver", "text="+uiEvent.getText());
                Log.d("FragmentReceiver", "number="+uiEvent.getNumber());
                return true; // to stop message propagation
        }
        return false;   // to let other components to process the message
    }
}

Message can use integer ID, string ID, or both for more complex control scenarios:

new UIEvent(12345, "button.ok.click"))
    .post(view);

The 'onMessage' for the above code:

public class FragmentReceiver extends Fragment implements UIEventListener {
//  .....
    @Override
    public boolean onMessage(@NonNull UIEvent uiEvent) {
        switch (uiEvent.code) {
            case 12345:
                if(uiEvent.what.equals("button.ok.click")){
                    // ...
                    return true; // to stop message propagation
                }
        }
        return false;   // to let other components to process the message
    }
}

When writing android library make sure to use 'namespace' to prevent collisions. Sending message inside library can look like:

new UIEvent("button.ok.click")
    .setNamespace("lib_name.company_name.com")
    .post(view);

Namespace "lib_name.company_name.com" is going to prevent ID collisions
when the library is distributed to third party developers.

And to receive this message inside library module

public class FragmentReceiver extends Fragment implements UIEventListener {
//  .....
    @Override
    public boolean onMessage(@NonNull UIEvent uiEvent) {
        // return false if this is not library message
        if (!uiEvent.getNamespace().equals("libname.company.com")) return false;

        switch (uiEvent.what){
            case "button.ok.click":
                Log.d(uiEvent.getText());
                return true; // to stop message propagation
        }
        return false;   // to let other objects to process message
    }
}

R8 / ProGuard

No special requirements for R8 or ProGuard

GitHub