Using Otto Event Bus to Communicate b/w Activity and Fragment.

By | January 1, 2018

Using Otto Event Bus to Communicate b/w Activity and Fragment.

Otto Event Bus is an Android Library that helps developers to communicate between Android Activity and Fragment and vice-versa.

Lets see a simple implementation of this.

Here I will pass a simple string from Activity to Fragment and Vice-versa.

Gradle

dependencies {
    compile 'com.squareup:otto:1.3.8'
}

Layout

Activity layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#cfcfcf">

    <RelativeLayout
        android:id="@+id/activityLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white">

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Activity"
            android:textStyle="bold"/>

        <TextView
            android:id="@+id/message"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/title"/>

        <EditText
            android:id="@+id/activityData"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/message"
            android:hint="pass data"/>

        <Button
            android:id="@+id/sendMessageToFragment"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/activityData"
            android:layout_centerHorizontal="true"
            android:onClick="sendMessageToFragment"
            android:text="Send Message To Fragment"/>

    </RelativeLayout>

    <LinearLayout
        android:id="@+id/fragmentContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/activityLayout"
        android:orientation="vertical">
    </LinearLayout>

</RelativeLayout>

Fragment Layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment"
        android:textStyle="bold"/>

    <TextView
        android:id="@+id/message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/title"/>

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/message"
        android:hint="Pass Data"/>

    <Button
        android:id="@+id/submit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText"
        android:layout_centerHorizontal="true"
        android:text="Send message to Activity"/>

</RelativeLayout>

Register and unregister for events

Event registration is done via the @Subcribe annotation on a public single parameter method. The method parameter is the event key, i.e., if such an data type is send via the Otto event bus the method is called.

Event receivers must register via the register method of the Bus class.

/* subscribe for string messages */

@Subscribe
public void getMessage(String s) {
}

Example

/* subscribe for DemoData messages */

@Subscribe
public void getMessage(DemoData data) {
Toast.makeText(getActivity(), data.getMessage(), Toast.LENGTH_LONG).show();
}

// You could do this in onStart...
OttoBus.getBus().register(this);

// Also don't forget to unregister
OttoBus.getBus().unregister(this);

How to send messages

OttoBus.getBus().post(new DemoData().getMessage());

Receive the last Event

Sometimes new components, like a dynamically created fragment, should receive event data during their creation. If this case component can register as producer for such event data with the @Produce annotation.

Event receivers must register via the register method of the Bus class.

@Produce
public String produceEvent() {
    return "Just Started";
}

Implementation

Instantiate Otto Library

import com.squareup.otto.Bus;

public class OttoBus {
    private static Bus sBus;
    public static Bus getBus() {
        if (sBus == null)
            sBus = new Bus();
        return sBus;
    }
}

Events Class

public class Events {

    public static class FragmentActivityMessage {

        private String message;

        public FragmentActivityMessage(String message) {
            this.message = message;
        }

        public String getMessage() {
            return message;
        }
    }

    public static class ActivityFragmentMessage {

        private String message;

        public ActivityFragmentMessage(String message) {
            this.message = message;
        }

        public String getMessage() {
            return message;
        }
    }

}

Activity

package otto_library_android.coderzheaven.com.ottolibraryandroiddemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import com.squareup.otto.Subscribe;

public class MainActivity extends AppCompatActivity {

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

    @Override
    protected void onStart() {
        super.onStart();
        OttoBus.getBus().register(this);
    }

    private void addFragment() {
        getSupportFragmentManager().beginTransaction().add(R.id.fragmentContainer, new DemoFragment()).commit();
    }

    public void sendMessageToFragment(View view) {
        EditText etMessage = findViewById(R.id.activityData);
        OttoBus.getBus().post(String.valueOf(etMessage.getText()));
    }

    @Subscribe
    public void getMessage(Events.ActivityFragmentMessage message) {
        TextView messageView = findViewById(R.id.message);
        messageView.setText(message.getMessage());
    }

    @Override
    protected void onStop() {
        super.onStop();
        OttoBus.getBus().unregister(this);
    }
}

Fragment

package otto_library_android.coderzheaven.com.ottolibraryandroiddemo;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.squareup.otto.Subscribe;

public class DemoFragment extends Fragment {

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

    @Override
    public void onStart() {
        super.onStart();
        OttoBus.getBus().register(this);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        setClickListener(view);
    }

    public void setClickListener(final View view) {
        Button btnSubmit = (Button) view.findViewById(R.id.submit);
        btnSubmit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMessageToActivity();
            }
        });
    }

    private void sendMessageToActivity() {
        EditText etMessage = getView().findViewById(R.id.editText);
        OttoBus.getBus().post(etMessage.getText().toString());
    }

    @Subscribe
    public void getMessage(Events.FragmentActivityMessage message) {
        TextView messageView = getView().findViewById(R.id.message);
        messageView.setText(message.getMessage());
    }

    @Override
    public void onStop() {
        super.onStop();
        OttoBus.getBus().unregister(this);
    }
}

Source Code

You can download the source code from here.

Leave a Reply

Your email address will not be published. Required fields are marked *